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,738 @@
|
|
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
|
+
====================================================================
|
15
|
+
Synthesis Plugins (:mod:`qiskit.transpiler.passes.synthesis.plugin`)
|
16
|
+
====================================================================
|
17
|
+
|
18
|
+
.. currentmodule:: qiskit.transpiler.passes.synthesis.plugin
|
19
|
+
|
20
|
+
This module defines the plugin interfaces for the synthesis transpiler passes
|
21
|
+
in Qiskit. These provide a hook point for external python packages to implement
|
22
|
+
their own synthesis techniques and have them seamlessly exposed as opt-in
|
23
|
+
options to users when they run :func:`~qiskit.compiler.transpile`.
|
24
|
+
|
25
|
+
The plugin interfaces are built using setuptools
|
26
|
+
`entry points <https://setuptools.readthedocs.io/en/latest/userguide/entry_point.html>`__
|
27
|
+
which enable packages external to qiskit to advertise they include a synthesis
|
28
|
+
plugin.
|
29
|
+
|
30
|
+
See :mod:`qiskit.transpiler.preset_passmanagers.plugin` for details on how
|
31
|
+
to write plugins for transpiler stages.
|
32
|
+
|
33
|
+
Synthesis Plugin API
|
34
|
+
====================
|
35
|
+
|
36
|
+
Unitary Synthesis Plugin API
|
37
|
+
----------------------------
|
38
|
+
|
39
|
+
.. autosummary::
|
40
|
+
:toctree: ../stubs/
|
41
|
+
|
42
|
+
UnitarySynthesisPlugin
|
43
|
+
UnitarySynthesisPluginManager
|
44
|
+
unitary_synthesis_plugin_names
|
45
|
+
|
46
|
+
High-Level Synthesis Plugin API
|
47
|
+
-------------------------------
|
48
|
+
|
49
|
+
.. autosummary::
|
50
|
+
:toctree: ../stubs/
|
51
|
+
|
52
|
+
HighLevelSynthesisPlugin
|
53
|
+
HighLevelSynthesisPluginManager
|
54
|
+
high_level_synthesis_plugin_names
|
55
|
+
|
56
|
+
Writing Plugins
|
57
|
+
===============
|
58
|
+
|
59
|
+
Unitary Synthesis Plugins
|
60
|
+
-------------------------
|
61
|
+
|
62
|
+
To write a unitary synthesis plugin there are 2 main steps. The first step is
|
63
|
+
to create a subclass of the abstract plugin class:
|
64
|
+
:class:`~qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin`.
|
65
|
+
The plugin class defines the interface and contract for unitary synthesis
|
66
|
+
plugins. The primary method is
|
67
|
+
:meth:`~qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin.run`
|
68
|
+
which takes in a single positional argument, a unitary matrix as a numpy array,
|
69
|
+
and is expected to return a :class:`~qiskit.dagcircuit.DAGCircuit` object
|
70
|
+
representing the synthesized circuit from that unitary matrix. Then to inform
|
71
|
+
the Qiskit transpiler about what information is necessary for the pass there
|
72
|
+
are several required property methods that need to be implemented such as
|
73
|
+
``supports_basis_gates`` and ``supports_coupling_map`` depending on whether the
|
74
|
+
plugin supports and/or requires that input to perform synthesis. For the full
|
75
|
+
details refer to the
|
76
|
+
:class:`~qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin`
|
77
|
+
documentation for all the required fields. An example plugin class would look
|
78
|
+
something like::
|
79
|
+
|
80
|
+
from qiskit.transpiler.passes.synthesis import plugin
|
81
|
+
from qiskit_plugin_pkg.synthesis import generate_dag_circuit_from_matrix
|
82
|
+
|
83
|
+
|
84
|
+
class SpecialUnitarySynthesis(plugin.UnitarySynthesisPlugin):
|
85
|
+
@property
|
86
|
+
def supports_basis_gates(self):
|
87
|
+
return True
|
88
|
+
|
89
|
+
@property
|
90
|
+
def supports_coupling_map(self):
|
91
|
+
return False
|
92
|
+
|
93
|
+
@property
|
94
|
+
def supports_natural_direction(self):
|
95
|
+
return False
|
96
|
+
|
97
|
+
@property
|
98
|
+
def supports_pulse_optimize(self):
|
99
|
+
return False
|
100
|
+
|
101
|
+
@property
|
102
|
+
def supports_gate_lengths(self):
|
103
|
+
return False
|
104
|
+
|
105
|
+
@property
|
106
|
+
def supports_gate_errors(self):
|
107
|
+
return False
|
108
|
+
|
109
|
+
@property
|
110
|
+
def supports_gate_lengths_by_qubit(self):
|
111
|
+
return False
|
112
|
+
|
113
|
+
@property
|
114
|
+
def supports_gate_errors_by_qubit(self):
|
115
|
+
return False
|
116
|
+
|
117
|
+
@property
|
118
|
+
def min_qubits(self):
|
119
|
+
return None
|
120
|
+
|
121
|
+
@property
|
122
|
+
def max_qubits(self):
|
123
|
+
return None
|
124
|
+
|
125
|
+
@property
|
126
|
+
def supported_bases(self):
|
127
|
+
return None
|
128
|
+
|
129
|
+
def run(self, unitary, **options):
|
130
|
+
basis_gates = options['basis_gates']
|
131
|
+
dag_circuit = generate_dag_circuit_from_matrix(unitary, basis_gates)
|
132
|
+
return dag_circuit
|
133
|
+
|
134
|
+
If for some reason the available inputs to the
|
135
|
+
:meth:`~qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin.run`
|
136
|
+
method are insufficient please open an issue and we can discuss expanding the
|
137
|
+
plugin interface with new opt-in inputs that can be added in a backwards
|
138
|
+
compatible manner for future releases. Do note though that this plugin interface
|
139
|
+
is considered stable and guaranteed to not change in a breaking manner. If
|
140
|
+
changes are needed (for example to expand the available optional input options)
|
141
|
+
it will be done in a way that will **not** require changes from existing
|
142
|
+
plugins.
|
143
|
+
|
144
|
+
.. note::
|
145
|
+
|
146
|
+
All methods prefixed with ``supports_`` are reserved on a
|
147
|
+
``UnitarySynthesisPlugin`` derived class for part of the interface. You
|
148
|
+
should not define any custom ``supports_*`` methods on a subclass that
|
149
|
+
are not defined in the abstract class.
|
150
|
+
|
151
|
+
|
152
|
+
The second step is to expose the
|
153
|
+
:class:`~qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin` as
|
154
|
+
a setuptools entry point in the package metadata. This is done by simply adding
|
155
|
+
an ``entry-points`` table in ``pyproject.toml`` for the plugin package with the necessary entry
|
156
|
+
points under the ``qiskit.unitary_synthesis`` namespace. For example:
|
157
|
+
|
158
|
+
.. code-block:: toml
|
159
|
+
|
160
|
+
[project.entry-points."qiskit.unitary_synthesis"]
|
161
|
+
"special" = "qiskit_plugin_pkg.module.plugin:SpecialUnitarySynthesis"
|
162
|
+
|
163
|
+
There isn't a limit to the number of plugins a single package can
|
164
|
+
include as long as each plugin has a unique name. So a single package can
|
165
|
+
expose multiple plugins if necessary. The name ``default`` is used by Qiskit
|
166
|
+
itself and can't be used in a plugin.
|
167
|
+
|
168
|
+
Unitary Synthesis Plugin Configuration
|
169
|
+
''''''''''''''''''''''''''''''''''''''
|
170
|
+
|
171
|
+
For some unitary synthesis plugins that expose multiple options and tunables
|
172
|
+
the plugin interface has an option for users to provide a free form
|
173
|
+
configuration dictionary. This will be passed through to the ``run()`` method
|
174
|
+
as the ``options`` kwarg. If your plugin has these configuration options you
|
175
|
+
should clearly document how a user should specify these configuration options
|
176
|
+
and how they're used as it's a free form field.
|
177
|
+
|
178
|
+
High-Level Synthesis Plugins
|
179
|
+
----------------------------
|
180
|
+
|
181
|
+
Writing a high-level synthesis plugin is conceptually similar to writing a
|
182
|
+
unitary synthesis plugin. The first step is to create a subclass of the
|
183
|
+
abstract plugin class:
|
184
|
+
:class:`~qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPlugin`,
|
185
|
+
which defines the interface and contract for high-level synthesis plugins.
|
186
|
+
The primary method is
|
187
|
+
:meth:`~qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPlugin.run`.
|
188
|
+
The positional argument ``high_level_object`` specifies the "higher-level-object" to
|
189
|
+
be synthesized, which is any object of type :class:`~qiskit.circuit.Operation`
|
190
|
+
(including, for example,
|
191
|
+
:class:`~qiskit.circuit.library.generalized_gates.linear_function.LinearFunction` or
|
192
|
+
:class:`~qiskit.quantum_info.operators.symplectic.clifford.Clifford`).
|
193
|
+
The keyword argument ``target`` specifies the target backend, allowing the plugin
|
194
|
+
to access all target-specific information,
|
195
|
+
such as the coupling map, the supported gate set, and so on. The keyword argument
|
196
|
+
``coupling_map`` only specifies the coupling map, and is only used when ``target``
|
197
|
+
is not specified.
|
198
|
+
The keyword argument ``qubits`` specifies the list of qubits over which the
|
199
|
+
higher-level-object is defined, in case the synthesis is done on the physical circuit.
|
200
|
+
The value of ``None`` indicates that the layout has not yet been chosen and the physical qubits
|
201
|
+
in the target or coupling map that this operation is operating on has not yet been determined.
|
202
|
+
Additionally, plugin-specific options and tunables can be specified via ``options``,
|
203
|
+
which is a free form configuration dictionary.
|
204
|
+
If your plugin has these configuration options you
|
205
|
+
should clearly document how a user should specify these configuration options
|
206
|
+
and how they're used as it's a free form field.
|
207
|
+
The method
|
208
|
+
:meth:`~qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPlugin.run`
|
209
|
+
is expected to return a :class:`~qiskit.circuit.QuantumCircuit` object
|
210
|
+
representing the synthesized circuit from that higher-level-object.
|
211
|
+
It is also allowed to return ``None`` representing that the synthesis method is
|
212
|
+
unable to synthesize the given higher-level-object.
|
213
|
+
The actual synthesis of higher-level objects is performed by
|
214
|
+
:class:`~qiskit.transpiler.passes.synthesis.high_level_synthesis.HighLevelSynthesis`
|
215
|
+
transpiler pass.
|
216
|
+
For the full details refer to the
|
217
|
+
:class:`~qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPlugin`
|
218
|
+
documentation for all the required fields. An example plugin class would look
|
219
|
+
something like::
|
220
|
+
|
221
|
+
from qiskit.transpiler.passes.synthesis.plugin import HighLevelSynthesisPlugin
|
222
|
+
from qiskit.synthesis.clifford import synth_clifford_bm
|
223
|
+
|
224
|
+
|
225
|
+
class SpecialSynthesisClifford(HighLevelSynthesisPlugin):
|
226
|
+
|
227
|
+
def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
|
228
|
+
if higher_level_object.num_qubits <= 3:
|
229
|
+
return synth_clifford_bm(high_level_object)
|
230
|
+
else:
|
231
|
+
return None
|
232
|
+
|
233
|
+
The above example creates a plugin to synthesize objects of type
|
234
|
+
:class:`.Clifford` that have
|
235
|
+
at most 3 qubits, using the method ``synth_clifford_bm``.
|
236
|
+
|
237
|
+
The second step is to expose the
|
238
|
+
:class:`~qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPlugin` as
|
239
|
+
a setuptools entry point in the package metadata. This is done by adding
|
240
|
+
an ``entry-points`` table in ``pyproject.toml`` for the plugin package with the necessary entry
|
241
|
+
points under the ``qiskit.synthesis`` namespace. For example:
|
242
|
+
|
243
|
+
.. code-block:: toml
|
244
|
+
|
245
|
+
[project.entry-points."qiskit.synthesis"]
|
246
|
+
"clifford.special" = "qiskit_plugin_pkg.module.plugin:SpecialSynthesisClifford"
|
247
|
+
|
248
|
+
The ``name`` consists of two parts separated by dot ".": the name of the
|
249
|
+
type of :class:`~qiskit.circuit.Operation` to which the synthesis plugin applies
|
250
|
+
(``clifford``), and the name of the plugin (``special``).
|
251
|
+
There isn't a limit to the number of plugins a single package can
|
252
|
+
include as long as each plugin has a unique name.
|
253
|
+
|
254
|
+
Using Plugins
|
255
|
+
=============
|
256
|
+
|
257
|
+
Unitary Synthesis Plugins
|
258
|
+
-------------------------
|
259
|
+
|
260
|
+
To use a plugin all you need to do is install the package that includes a
|
261
|
+
synthesis plugin. Then Qiskit will automatically discover the installed
|
262
|
+
plugins and expose them as valid options for the appropriate
|
263
|
+
:func:`~qiskit.compiler.transpile` kwargs and pass constructors. If there are
|
264
|
+
any installed plugins which can't be loaded/imported this will be logged to
|
265
|
+
Python logging.
|
266
|
+
|
267
|
+
To get the installed list of installed unitary synthesis plugins you can use the
|
268
|
+
:func:`qiskit.transpiler.passes.synthesis.plugin.unitary_synthesis_plugin_names`
|
269
|
+
function.
|
270
|
+
|
271
|
+
.. _using-high-level-synthesis-plugins:
|
272
|
+
|
273
|
+
High-level Synthesis Plugins
|
274
|
+
----------------------------
|
275
|
+
|
276
|
+
To use a high-level synthesis plugin, you first instantiate an :class:`.HLSConfig` to
|
277
|
+
store the names of the plugins to use for various high-level objects.
|
278
|
+
For example::
|
279
|
+
|
280
|
+
HLSConfig(permutation=["acg"], clifford=["layers"], linear_function=["pmh"])
|
281
|
+
|
282
|
+
creates a high-level synthesis configuration that uses the ``acg`` plugin
|
283
|
+
for synthesizing :class:`.PermutationGate` objects, the ``layers`` plugin
|
284
|
+
for synthesizing :class:`.Clifford` objects, and the ``pmh`` plugin for synthesizing
|
285
|
+
:class:`.LinearFunction` objects. The keyword arguments are the :attr:`.Operation.name` fields of
|
286
|
+
the relevant objects. For example, all :class:`.Clifford` operations have the
|
287
|
+
:attr:`~.Operation.name` ``clifford``, so this is used as the keyword argument. You can specify
|
288
|
+
any keyword argument here that you have installed plugins to handle, including custom user objects
|
289
|
+
if you have plugins installed for them. See :class:`.HLSConfig` for more detail on alternate
|
290
|
+
formats for configuring the plugins within each argument.
|
291
|
+
|
292
|
+
For each high-level object, the list of given plugins are tried in sequence until one of them
|
293
|
+
succeeds (in the example above, each list only contains a single plugin). In addition to specifying
|
294
|
+
a plugin by its name, you can instead pass a ``(name, options)`` tuple, where the second element of
|
295
|
+
the tuple is a dictionary containing options for the plugin.
|
296
|
+
|
297
|
+
Once created you then pass this :class:`.HLSConfig` object into the
|
298
|
+
``hls_config`` argument for :func:`.transpile` or :func:`.generate_preset_pass_manager`
|
299
|
+
which will use the specified plugins as part of the larger compilation workflow.
|
300
|
+
|
301
|
+
To get a list of installed high level synthesis plugins for any given :attr:`.Operation.name`, you
|
302
|
+
can use the :func:`.high_level_synthesis_plugin_names` function, passing the desired ``name`` as the
|
303
|
+
argument::
|
304
|
+
|
305
|
+
high_level_synthesis_plugin_names("clifford")
|
306
|
+
|
307
|
+
will return a list of all the installed Clifford synthesis plugins.
|
308
|
+
|
309
|
+
Available Plugins
|
310
|
+
=================
|
311
|
+
|
312
|
+
High-level synthesis plugins that are directly available in Qiskit include plugins
|
313
|
+
for synthesizing :class:`.Clifford` objects, :class:`.LinearFunction` objects, and
|
314
|
+
:class:`.PermutationGate` objects.
|
315
|
+
Some of these plugins implicitly target all-to-all connectivity. This is not a
|
316
|
+
practical limitation since
|
317
|
+
:class:`~qiskit.transpiler.passes.synthesis.high_level_synthesis.HighLevelSynthesis`
|
318
|
+
typically runs before layout and routing, which will ensure that the final circuit
|
319
|
+
adheres to the device connectivity by inserting additional SWAP gates. A good example
|
320
|
+
is the permutation synthesis plugin ``ACGSynthesisPermutation`` which can synthesize
|
321
|
+
any permutation with at most 2 layers of SWAP gates.
|
322
|
+
On the other hand, some plugins implicitly target linear connectivity.
|
323
|
+
Typically, the synthesizing circuits have larger depth and the number of gates,
|
324
|
+
however no additional SWAP gates would be inserted if the following layout pass chose a
|
325
|
+
consecutive line of qubits inside the topology of the device. A good example of this is
|
326
|
+
the permutation synthesis plugin ``KMSSynthesisPermutation`` which can synthesize any
|
327
|
+
permutation of ``n`` qubits in depth ``n``. Typically, it is difficult to know in advance
|
328
|
+
which of the two approaches: synthesizing circuits for all-to-all connectivity and
|
329
|
+
inserting SWAP gates vs. synthesizing circuits for linear connectivity and inserting less
|
330
|
+
or no SWAP gates lead a better final circuit, so it likely makes sense to try both and
|
331
|
+
see which gives better results.
|
332
|
+
Finally, some plugins can target a given connectivity, and hence should be run after the
|
333
|
+
layout is set. In this case the synthesized circuit automatically adheres to
|
334
|
+
the topology of the device. A good example of this is the permutation synthesis plugin
|
335
|
+
``TokenSwapperSynthesisPermutation`` which is able to synthesize arbitrary permutations
|
336
|
+
with respect to arbitrary coupling maps.
|
337
|
+
For more detail, please refer to description of each individual plugin.
|
338
|
+
|
339
|
+
Below are the synthesis plugin classes available in Qiskit. These classes should not be
|
340
|
+
used directly, but instead should be used through the plugin interface documented
|
341
|
+
above. The classes are listed here to ease finding the documentation for each of the
|
342
|
+
included plugins and to ease the comparison between different synthesis methods for
|
343
|
+
a given object.
|
344
|
+
|
345
|
+
|
346
|
+
Unitary Synthesis Plugins
|
347
|
+
-------------------------
|
348
|
+
|
349
|
+
.. automodule:: qiskit.transpiler.passes.synthesis.aqc_plugin
|
350
|
+
:no-members:
|
351
|
+
:no-inherited-members:
|
352
|
+
:no-special-members:
|
353
|
+
|
354
|
+
.. automodule:: qiskit.transpiler.passes.synthesis.unitary_synthesis
|
355
|
+
:no-members:
|
356
|
+
:no-inherited-members:
|
357
|
+
:no-special-members:
|
358
|
+
|
359
|
+
.. automodule:: qiskit.transpiler.passes.synthesis.solovay_kitaev_synthesis
|
360
|
+
:no-members:
|
361
|
+
:no-inherited-members:
|
362
|
+
:no-special-members:
|
363
|
+
|
364
|
+
|
365
|
+
High Level Synthesis
|
366
|
+
--------------------
|
367
|
+
|
368
|
+
For each high-level object we give a table that lists all of its plugins available
|
369
|
+
directly in Qiskit. We include the name of the plugin, the class of the plugin,
|
370
|
+
the targeted connectivity map and optionally additional information. Recall the plugins
|
371
|
+
should be used via the previously described :class:`.HLSConfig`, for example::
|
372
|
+
|
373
|
+
HLSConfig(permutation=["kms"])
|
374
|
+
|
375
|
+
creates a high-level synthesis configuration that uses the ``kms`` plugin
|
376
|
+
for synthesizing :class:`.PermutationGate` objects -- i.e. those with
|
377
|
+
``name = "permutation"``. In this case, the plugin name is "kms", the plugin class
|
378
|
+
is :class:`~.KMSSynthesisPermutation`. This particular synthesis algorithm created
|
379
|
+
a circuit adhering to the linear nearest-neighbor connectivity.
|
380
|
+
|
381
|
+
.. automodule:: qiskit.transpiler.passes.synthesis.hls_plugins
|
382
|
+
:no-members:
|
383
|
+
:no-inherited-members:
|
384
|
+
:no-special-members:
|
385
|
+
"""
|
386
|
+
|
387
|
+
import abc
|
388
|
+
from typing import List
|
389
|
+
|
390
|
+
import stevedore
|
391
|
+
|
392
|
+
|
393
|
+
class UnitarySynthesisPlugin(abc.ABC):
|
394
|
+
"""Abstract unitary synthesis plugin class
|
395
|
+
|
396
|
+
This abstract class defines the interface for unitary synthesis plugins.
|
397
|
+
"""
|
398
|
+
|
399
|
+
@property
|
400
|
+
@abc.abstractmethod
|
401
|
+
def max_qubits(self):
|
402
|
+
"""Return the maximum number of qubits the unitary synthesis plugin supports.
|
403
|
+
|
404
|
+
If the size of the unitary to be synthesized exceeds this value the
|
405
|
+
``default`` plugin will be used. If there is no upper bound return
|
406
|
+
``None`` and all unitaries (``>= min_qubits`` if it's defined) will be
|
407
|
+
passed to this plugin when it's enabled.
|
408
|
+
"""
|
409
|
+
pass
|
410
|
+
|
411
|
+
@property
|
412
|
+
@abc.abstractmethod
|
413
|
+
def min_qubits(self):
|
414
|
+
"""Return the minimum number of qubits the unitary synthesis plugin supports.
|
415
|
+
|
416
|
+
If the size of the unitary to be synthesized is below this value the
|
417
|
+
``default`` plugin will be used. If there is no lower bound return
|
418
|
+
``None`` and all unitaries (``<= max_qubits`` if it's defined) will be
|
419
|
+
passed to this plugin when it's enabled.
|
420
|
+
"""
|
421
|
+
pass
|
422
|
+
|
423
|
+
@property
|
424
|
+
@abc.abstractmethod
|
425
|
+
def supports_basis_gates(self):
|
426
|
+
"""Return whether the plugin supports taking ``basis_gates``
|
427
|
+
|
428
|
+
If this returns ``True`` the plugin's ``run()`` method will be
|
429
|
+
passed a ``basis_gates`` kwarg with a list of gate names the target
|
430
|
+
backend supports. For example, ``['sx', 'x', 'cx', 'id', 'rz']``."""
|
431
|
+
pass
|
432
|
+
|
433
|
+
@property
|
434
|
+
@abc.abstractmethod
|
435
|
+
def supports_coupling_map(self):
|
436
|
+
"""Return whether the plugin supports taking ``coupling_map``
|
437
|
+
|
438
|
+
If this returns ``True`` the plugin's ``run()`` method will receive
|
439
|
+
one kwarg ``coupling_map``. The ``coupling_map`` kwarg will be set to a
|
440
|
+
tuple with the first element being a
|
441
|
+
:class:`~qiskit.transpiler.CouplingMap` object representing the qubit
|
442
|
+
connectivity of the target backend, the second element will be a list
|
443
|
+
of integers that represent the qubit indices in the coupling map that
|
444
|
+
unitary is on. Note that if the target backend doesn't have a coupling
|
445
|
+
map set, the ``coupling_map`` kwarg's value will be ``(None, qubit_indices)``.
|
446
|
+
"""
|
447
|
+
pass
|
448
|
+
|
449
|
+
@property
|
450
|
+
@abc.abstractmethod
|
451
|
+
def supports_natural_direction(self):
|
452
|
+
"""Return whether the plugin supports a toggle for considering
|
453
|
+
directionality of 2-qubit gates as ``natural_direction``.
|
454
|
+
|
455
|
+
Refer to the documentation for :class:`~qiskit.transpiler.passes.UnitarySynthesis`
|
456
|
+
for the possible values and meaning of these values.
|
457
|
+
"""
|
458
|
+
pass
|
459
|
+
|
460
|
+
@property
|
461
|
+
@abc.abstractmethod
|
462
|
+
def supports_pulse_optimize(self):
|
463
|
+
"""Return whether the plugin supports a toggle to optimize pulses
|
464
|
+
during synthesis as ``pulse_optimize``.
|
465
|
+
|
466
|
+
Refer to the documentation for :class:`~qiskit.transpiler.passes.UnitarySynthesis`
|
467
|
+
for the possible values and meaning of these values.
|
468
|
+
"""
|
469
|
+
pass
|
470
|
+
|
471
|
+
@property
|
472
|
+
def supports_gate_lengths_by_qubit(self):
|
473
|
+
"""Return whether the plugin supports taking ``gate_lengths_by_qubit``
|
474
|
+
|
475
|
+
This differs from ``supports_gate_lengths``/``gate_lengths`` by using a different
|
476
|
+
view of the same data. Instead of being keyed by gate name this is keyed by qubit
|
477
|
+
and uses :class:`~.Gate` instances to represent gates (instead of gate names)
|
478
|
+
|
479
|
+
``gate_lengths_by_qubit`` will be a dictionary in the form of
|
480
|
+
``{(qubits,): [Gate, length]}``. For example::
|
481
|
+
|
482
|
+
{
|
483
|
+
(0,): [SXGate(): 0.0006149355812506126, RZGate(): 0.0],
|
484
|
+
(0, 1): [CXGate(): 0.012012477900732316]
|
485
|
+
}
|
486
|
+
|
487
|
+
where the ``length`` value is in units of seconds.
|
488
|
+
|
489
|
+
Do note that this dictionary might not be complete or could be empty
|
490
|
+
as it depends on the target backend reporting gate lengths on every
|
491
|
+
gate for each qubit.
|
492
|
+
|
493
|
+
This defaults to False
|
494
|
+
"""
|
495
|
+
return False
|
496
|
+
|
497
|
+
@property
|
498
|
+
def supports_gate_errors_by_qubit(self):
|
499
|
+
"""Return whether the plugin supports taking ``gate_errors_by_qubit``
|
500
|
+
|
501
|
+
This differs from ``supports_gate_errors``/``gate_errors`` by using a different
|
502
|
+
view of the same data. Instead of being keyed by gate name this is keyed by qubit
|
503
|
+
and uses :class:`~.Gate` instances to represent gates (instead of gate names).
|
504
|
+
|
505
|
+
``gate_errors_by_qubit`` will be a dictionary in the form of
|
506
|
+
``{(qubits,): [Gate, error]}``. For example::
|
507
|
+
|
508
|
+
{
|
509
|
+
(0,): [SXGate(): 0.0006149355812506126, RZGate(): 0.0],
|
510
|
+
(0, 1): [CXGate(): 0.012012477900732316]
|
511
|
+
}
|
512
|
+
|
513
|
+
Do note that this dictionary might not be complete or could be empty
|
514
|
+
as it depends on the target backend reporting gate errors on every
|
515
|
+
gate for each qubit. The gate error rates reported in ``gate_errors``
|
516
|
+
are provided by the target device ``Backend`` object and the exact
|
517
|
+
meaning might be different depending on the backend.
|
518
|
+
|
519
|
+
This defaults to False
|
520
|
+
"""
|
521
|
+
return False
|
522
|
+
|
523
|
+
@property
|
524
|
+
@abc.abstractmethod
|
525
|
+
def supports_gate_lengths(self):
|
526
|
+
"""Return whether the plugin supports taking ``gate_lengths``
|
527
|
+
|
528
|
+
``gate_lengths`` will be a dictionary in the form of
|
529
|
+
``{gate_name: {(qubit_1, qubit_2): length}}``. For example::
|
530
|
+
|
531
|
+
{
|
532
|
+
'sx': {(0,): 0.0006149355812506126, (1,): 0.0006149355812506126},
|
533
|
+
'cx': {(0, 1): 0.012012477900732316, (1, 0): 5.191111111111111e-07}
|
534
|
+
}
|
535
|
+
|
536
|
+
where the ``length`` value is in units of seconds.
|
537
|
+
|
538
|
+
Do note that this dictionary might not be complete or could be empty
|
539
|
+
as it depends on the target backend reporting gate lengths on every
|
540
|
+
gate for each qubit.
|
541
|
+
"""
|
542
|
+
pass
|
543
|
+
|
544
|
+
@property
|
545
|
+
@abc.abstractmethod
|
546
|
+
def supports_gate_errors(self):
|
547
|
+
"""Return whether the plugin supports taking ``gate_errors``
|
548
|
+
|
549
|
+
``gate_errors`` will be a dictionary in the form of
|
550
|
+
``{gate_name: {(qubit_1, qubit_2): error}}``. For example::
|
551
|
+
|
552
|
+
{
|
553
|
+
'sx': {(0,): 0.0006149355812506126, (1,): 0.0006149355812506126},
|
554
|
+
'cx': {(0, 1): 0.012012477900732316, (1, 0): 5.191111111111111e-07}
|
555
|
+
}
|
556
|
+
|
557
|
+
Do note that this dictionary might not be complete or could be empty
|
558
|
+
as it depends on the target backend reporting gate errors on every
|
559
|
+
gate for each qubit. The gate error rates reported in ``gate_errors``
|
560
|
+
are provided by the target device ``Backend`` object and the exact
|
561
|
+
meaning might be different depending on the backend.
|
562
|
+
"""
|
563
|
+
pass
|
564
|
+
|
565
|
+
@property
|
566
|
+
@abc.abstractmethod
|
567
|
+
def supported_bases(self):
|
568
|
+
"""Returns a dictionary of supported bases for synthesis
|
569
|
+
|
570
|
+
This is expected to return a dictionary where the key is a string
|
571
|
+
basis and the value is a list of gate names that the basis works in.
|
572
|
+
If the synthesis method doesn't support multiple bases this should
|
573
|
+
return ``None``. For example::
|
574
|
+
|
575
|
+
{
|
576
|
+
"XZX": ["rz", "rx"],
|
577
|
+
"XYX": ["rx", "ry"],
|
578
|
+
}
|
579
|
+
|
580
|
+
If a dictionary is returned by this method the run kwargs will be
|
581
|
+
passed a parameter ``matched_basis`` which contains a list of the
|
582
|
+
basis strings (i.e. keys in the dictionary) which match the target basis
|
583
|
+
gate set for the transpilation. If no entry in the dictionary matches
|
584
|
+
the target basis gate set then the ``matched_basis`` kwarg will be set
|
585
|
+
to an empty list, and a plugin can choose how to deal with the target
|
586
|
+
basis gate set not matching the plugin's capabilities.
|
587
|
+
"""
|
588
|
+
pass
|
589
|
+
|
590
|
+
@property
|
591
|
+
def supports_target(self):
|
592
|
+
"""Whether the plugin supports taking ``target`` as an option
|
593
|
+
|
594
|
+
``target`` will be a :class:`~.Target` object representing the target
|
595
|
+
device for the output of the synthesis pass.
|
596
|
+
|
597
|
+
By default this will be ``False`` since the plugin interface predates
|
598
|
+
the :class:`~.Target` class. If a plugin returns ``True`` for this
|
599
|
+
attribute, it is expected that the plugin will use the
|
600
|
+
:class:`~.Target` instead of the values passed if any of
|
601
|
+
``supports_gate_lengths``, ``supports_gate_errors``,
|
602
|
+
``supports_coupling_map``, and ``supports_basis_gates`` are set
|
603
|
+
(although ideally all those parameters should contain duplicate
|
604
|
+
information).
|
605
|
+
"""
|
606
|
+
return False
|
607
|
+
|
608
|
+
@abc.abstractmethod
|
609
|
+
def run(self, unitary, **options):
|
610
|
+
"""Run synthesis for the given unitary matrix
|
611
|
+
|
612
|
+
Args:
|
613
|
+
unitary (numpy.ndarray): The unitary matrix to synthesize to a
|
614
|
+
:class:`~qiskit.dagcircuit.DAGCircuit` object
|
615
|
+
options: The optional kwargs that are passed based on the output
|
616
|
+
the ``support_*`` methods on the class. Refer to the
|
617
|
+
documentation for these methods on
|
618
|
+
:class:`~qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin`
|
619
|
+
to see what the keys and values are.
|
620
|
+
|
621
|
+
Returns:
|
622
|
+
DAGCircuit: The dag circuit representation of the unitary. Alternatively, you can return
|
623
|
+
a tuple of the form ``(dag, wires)`` where ``dag`` is the dag circuit representation of
|
624
|
+
the circuit representation of the unitary and ``wires`` is the mapping wires to use for
|
625
|
+
:meth:`qiskit.dagcircuit.DAGCircuit.substitute_node_with_dag`. If you return a tuple
|
626
|
+
and ``wires`` is ``None`` this will behave just as if only a
|
627
|
+
:class:`~qiskit.dagcircuit.DAGCircuit` was returned. Additionally if this returns
|
628
|
+
``None`` no substitution will be made.
|
629
|
+
|
630
|
+
"""
|
631
|
+
pass
|
632
|
+
|
633
|
+
|
634
|
+
class UnitarySynthesisPluginManager:
|
635
|
+
"""Unitary Synthesis plugin manager class
|
636
|
+
|
637
|
+
This class tracks the installed plugins, it has a single property,
|
638
|
+
``ext_plugins`` which contains a list of stevedore plugin objects.
|
639
|
+
"""
|
640
|
+
|
641
|
+
def __init__(self):
|
642
|
+
self.ext_plugins = stevedore.ExtensionManager(
|
643
|
+
"qiskit.unitary_synthesis", invoke_on_load=True, propagate_map_exceptions=True
|
644
|
+
)
|
645
|
+
|
646
|
+
|
647
|
+
def unitary_synthesis_plugin_names():
|
648
|
+
"""Return a list of installed unitary synthesis plugin names
|
649
|
+
|
650
|
+
Returns:
|
651
|
+
list: A list of the installed unitary synthesis plugin names. The plugin names are valid
|
652
|
+
values for the :func:`~qiskit.compiler.transpile` kwarg ``unitary_synthesis_method``.
|
653
|
+
"""
|
654
|
+
# NOTE: This is not a shared global instance to avoid an import cycle
|
655
|
+
# at load time for the default plugin.
|
656
|
+
plugins = UnitarySynthesisPluginManager()
|
657
|
+
return plugins.ext_plugins.names()
|
658
|
+
|
659
|
+
|
660
|
+
class HighLevelSynthesisPlugin(abc.ABC):
|
661
|
+
"""Abstract high-level synthesis plugin class.
|
662
|
+
|
663
|
+
This abstract class defines the interface for high-level synthesis plugins.
|
664
|
+
"""
|
665
|
+
|
666
|
+
@abc.abstractmethod
|
667
|
+
def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
|
668
|
+
"""Run synthesis for the given Operation.
|
669
|
+
|
670
|
+
Args:
|
671
|
+
high_level_object (Operation): The Operation to synthesize to a
|
672
|
+
:class:`~qiskit.dagcircuit.DAGCircuit` object.
|
673
|
+
coupling_map (CouplingMap): The coupling map of the backend
|
674
|
+
in case synthesis is done on a physical circuit.
|
675
|
+
target (Target): A target representing the target backend.
|
676
|
+
qubits (list): List of qubits over which the operation is defined
|
677
|
+
in case synthesis is done on a physical circuit.
|
678
|
+
options: Additional method-specific optional kwargs.
|
679
|
+
|
680
|
+
Returns:
|
681
|
+
QuantumCircuit: The quantum circuit representation of the Operation
|
682
|
+
when successful, and ``None`` otherwise.
|
683
|
+
"""
|
684
|
+
pass
|
685
|
+
|
686
|
+
|
687
|
+
class HighLevelSynthesisPluginManager:
|
688
|
+
"""Class tracking the installed high-level-synthesis plugins."""
|
689
|
+
|
690
|
+
def __init__(self):
|
691
|
+
self.plugins = stevedore.ExtensionManager(
|
692
|
+
"qiskit.synthesis", invoke_on_load=True, propagate_map_exceptions=True
|
693
|
+
)
|
694
|
+
|
695
|
+
# The registered plugin names should be of the form <OperationName.SynthesisMethodName>.
|
696
|
+
|
697
|
+
# Create a dict, mapping <OperationName> to the list of its <SynthesisMethodName>s.
|
698
|
+
self.plugins_by_op = {}
|
699
|
+
for plugin_name in self.plugins.names():
|
700
|
+
op_name, method_name = plugin_name.split(".")
|
701
|
+
if op_name not in self.plugins_by_op:
|
702
|
+
self.plugins_by_op[op_name] = []
|
703
|
+
self.plugins_by_op[op_name].append(method_name)
|
704
|
+
|
705
|
+
def method_names(self, op_name):
|
706
|
+
"""Returns plugin methods for op_name."""
|
707
|
+
if op_name in self.plugins_by_op:
|
708
|
+
return self.plugins_by_op[op_name]
|
709
|
+
else:
|
710
|
+
return []
|
711
|
+
|
712
|
+
def method(self, op_name, method_name):
|
713
|
+
"""Returns the plugin for ``op_name`` and ``method_name``."""
|
714
|
+
plugin_name = op_name + "." + method_name
|
715
|
+
return self.plugins[plugin_name].obj
|
716
|
+
|
717
|
+
def op_names(self):
|
718
|
+
"""Returns the names of high-level-objects with available synthesis methods."""
|
719
|
+
return list(self.plugins_by_op.keys())
|
720
|
+
|
721
|
+
|
722
|
+
def high_level_synthesis_plugin_names(op_name: str) -> List[str]:
|
723
|
+
"""Return a list of plugin names installed for a given high level object name
|
724
|
+
|
725
|
+
Args:
|
726
|
+
op_name: The operation name to find the installed plugins for. For example,
|
727
|
+
if you provide ``"clifford"`` as the input it will find all the installed
|
728
|
+
clifford synthesis plugins that can synthesize :class:`.Clifford` objects.
|
729
|
+
The name refers to the :attr:`.Operation.name` attribute of the relevant objects.
|
730
|
+
|
731
|
+
Returns:
|
732
|
+
A list of installed plugin names for the specified high level operation
|
733
|
+
|
734
|
+
"""
|
735
|
+
# NOTE: This is not a shared global instance to avoid an import cycle
|
736
|
+
# at load time for the default plugins.
|
737
|
+
plugin_manager = HighLevelSynthesisPluginManager()
|
738
|
+
return plugin_manager.method_names(op_name)
|