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,749 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2020.
|
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
|
+
Template matching in the backward direction, it takes an initial match, a
|
15
|
+
configuration of qubit, both circuit and template as inputs and the list
|
16
|
+
obtained from forward match. The result is a list of matches between the
|
17
|
+
template and the circuit.
|
18
|
+
|
19
|
+
|
20
|
+
**Reference:**
|
21
|
+
|
22
|
+
[1] Iten, R., Moyard, R., Metger, T., Sutter, D. and Woerner, S., 2020.
|
23
|
+
Exact and practical pattern matching for quantum circuit optimization.
|
24
|
+
`arXiv:1909.05270 <https://arxiv.org/abs/1909.05270>`_
|
25
|
+
|
26
|
+
"""
|
27
|
+
import heapq
|
28
|
+
|
29
|
+
from qiskit.circuit.controlledgate import ControlledGate
|
30
|
+
|
31
|
+
|
32
|
+
class Match:
|
33
|
+
"""
|
34
|
+
Object to represent a match and its qubit configurations.
|
35
|
+
"""
|
36
|
+
|
37
|
+
def __init__(self, match, qubit, clbit):
|
38
|
+
"""
|
39
|
+
Create a Match class with necessary arguments.
|
40
|
+
Args:
|
41
|
+
match (list): list of matched gates.
|
42
|
+
qubit (list): list of qubits configuration.
|
43
|
+
clbit (list): list of clbits configuration.
|
44
|
+
|
45
|
+
"""
|
46
|
+
# Match list
|
47
|
+
self.match = match
|
48
|
+
# Qubits list for circuit
|
49
|
+
self.qubit = [qubit]
|
50
|
+
# Clbits for template
|
51
|
+
self.clbit = [clbit]
|
52
|
+
|
53
|
+
|
54
|
+
class MatchingScenarios:
|
55
|
+
"""
|
56
|
+
Class to represent a matching scenario.
|
57
|
+
"""
|
58
|
+
|
59
|
+
def __init__(
|
60
|
+
self, circuit_matched, circuit_blocked, template_matched, template_blocked, matches, counter
|
61
|
+
):
|
62
|
+
"""
|
63
|
+
Create a MatchingScenarios class with necessary arguments.
|
64
|
+
Args:
|
65
|
+
circuit_matched (list): list of matchedwith attributes in the circuit.
|
66
|
+
circuit_blocked (list): list of isblocked attributes in the circuit.
|
67
|
+
template_matched (list): list of matchedwith attributes in the template.
|
68
|
+
template_blocked (list): list of isblocked attributes in the template.
|
69
|
+
matches (list): list of matches.
|
70
|
+
counter (int): counter of the number of circuit gates already considered.
|
71
|
+
"""
|
72
|
+
self.circuit_matched = circuit_matched
|
73
|
+
self.template_matched = template_matched
|
74
|
+
self.circuit_blocked = circuit_blocked
|
75
|
+
self.template_blocked = template_blocked
|
76
|
+
self.matches = matches
|
77
|
+
self.counter = counter
|
78
|
+
|
79
|
+
|
80
|
+
class MatchingScenariosList:
|
81
|
+
"""
|
82
|
+
Object to define a list of MatchingScenarios, with method to append
|
83
|
+
and pop elements.
|
84
|
+
"""
|
85
|
+
|
86
|
+
def __init__(self):
|
87
|
+
"""
|
88
|
+
Create an empty MatchingScenariosList.
|
89
|
+
"""
|
90
|
+
self.matching_scenarios_list = []
|
91
|
+
|
92
|
+
def append_scenario(self, matching):
|
93
|
+
"""
|
94
|
+
Append a scenario to the list.
|
95
|
+
Args:
|
96
|
+
matching (MatchingScenarios): a scenario of match.
|
97
|
+
"""
|
98
|
+
self.matching_scenarios_list.append(matching)
|
99
|
+
|
100
|
+
def pop_scenario(self):
|
101
|
+
"""
|
102
|
+
Pop the first scenario of the list.
|
103
|
+
Returns:
|
104
|
+
MatchingScenarios: a scenario of match.
|
105
|
+
"""
|
106
|
+
# Pop the first MatchingScenario and returns it
|
107
|
+
first = self.matching_scenarios_list[0]
|
108
|
+
self.matching_scenarios_list.pop(0)
|
109
|
+
return first
|
110
|
+
|
111
|
+
|
112
|
+
class BackwardMatch:
|
113
|
+
"""
|
114
|
+
Class BackwardMatch allows to run backward direction part of template
|
115
|
+
matching algorithm.
|
116
|
+
"""
|
117
|
+
|
118
|
+
def __init__(
|
119
|
+
self,
|
120
|
+
circuit_dag_dep,
|
121
|
+
template_dag_dep,
|
122
|
+
forward_matches,
|
123
|
+
node_id_c,
|
124
|
+
node_id_t,
|
125
|
+
qubits,
|
126
|
+
clbits=None,
|
127
|
+
heuristics_backward_param=None,
|
128
|
+
):
|
129
|
+
"""
|
130
|
+
Create a ForwardMatch class with necessary arguments.
|
131
|
+
Args:
|
132
|
+
circuit_dag_dep (DAGDependency): circuit in the dag dependency form.
|
133
|
+
template_dag_dep (DAGDependency): template in the dag dependency form.
|
134
|
+
forward_matches (list): list of match obtained in the forward direction.
|
135
|
+
node_id_c (int): index of the first gate matched in the circuit.
|
136
|
+
node_id_t (int): index of the first gate matched in the template.
|
137
|
+
qubits (list): list of considered qubits in the circuit.
|
138
|
+
clbits (list): list of considered clbits in the circuit.
|
139
|
+
heuristics_backward_param (list): list that contains the two parameters for
|
140
|
+
applying the heuristics (length and survivor).
|
141
|
+
"""
|
142
|
+
self.circuit_dag_dep = circuit_dag_dep.copy()
|
143
|
+
self.template_dag_dep = template_dag_dep.copy()
|
144
|
+
self.qubits = qubits
|
145
|
+
self.clbits = clbits if clbits is not None else []
|
146
|
+
self.node_id_c = node_id_c
|
147
|
+
self.node_id_t = node_id_t
|
148
|
+
self.forward_matches = forward_matches
|
149
|
+
self.match_final = []
|
150
|
+
self.heuristics_backward_param = (
|
151
|
+
heuristics_backward_param if heuristics_backward_param is not None else []
|
152
|
+
)
|
153
|
+
self.matching_list = MatchingScenariosList()
|
154
|
+
|
155
|
+
def _gate_indices(self):
|
156
|
+
"""
|
157
|
+
Function which returns the list of gates that are not match and not
|
158
|
+
blocked for the first scenario.
|
159
|
+
Returns:
|
160
|
+
list: list of gate id.
|
161
|
+
"""
|
162
|
+
gate_indices = []
|
163
|
+
|
164
|
+
current_dag = self.circuit_dag_dep
|
165
|
+
|
166
|
+
for node in current_dag.get_nodes():
|
167
|
+
if (not node.matchedwith) and (not node.isblocked):
|
168
|
+
gate_indices.append(node.node_id)
|
169
|
+
gate_indices.reverse()
|
170
|
+
return gate_indices
|
171
|
+
|
172
|
+
def _find_backward_candidates(self, template_blocked, matches):
|
173
|
+
"""
|
174
|
+
Function which returns the list possible backward candidates in the template dag.
|
175
|
+
Args:
|
176
|
+
template_blocked (list): list of attributes isblocked in the template circuit.
|
177
|
+
matches (list): list of matches.
|
178
|
+
Returns:
|
179
|
+
list: list of backward candidates (id).
|
180
|
+
"""
|
181
|
+
template_block = []
|
182
|
+
|
183
|
+
for node_id in range(self.node_id_t, self.template_dag_dep.size()):
|
184
|
+
if template_blocked[node_id]:
|
185
|
+
template_block.append(node_id)
|
186
|
+
|
187
|
+
matches_template = sorted(match[0] for match in matches)
|
188
|
+
|
189
|
+
successors = self.template_dag_dep.get_node(self.node_id_t).successors
|
190
|
+
potential = []
|
191
|
+
for index in range(self.node_id_t + 1, self.template_dag_dep.size()):
|
192
|
+
if (index not in successors) and (index not in template_block):
|
193
|
+
potential.append(index)
|
194
|
+
|
195
|
+
candidates_indices = list(set(potential) - set(matches_template))
|
196
|
+
candidates_indices = sorted(candidates_indices)
|
197
|
+
candidates_indices.reverse()
|
198
|
+
|
199
|
+
return candidates_indices
|
200
|
+
|
201
|
+
def _update_qarg_indices(self, qarg):
|
202
|
+
"""
|
203
|
+
Change qubits indices of the current circuit node in order to
|
204
|
+
be comparable the indices of the template qubits list.
|
205
|
+
Args:
|
206
|
+
qarg (list): list of qubits indices from the circuit for a given gate.
|
207
|
+
Returns:
|
208
|
+
list: circuit indices update for qubits.
|
209
|
+
"""
|
210
|
+
qarg_indices = []
|
211
|
+
for q in qarg:
|
212
|
+
if q in self.qubits:
|
213
|
+
qarg_indices.append(self.qubits.index(q))
|
214
|
+
if len(qarg) != len(qarg_indices):
|
215
|
+
qarg_indices = []
|
216
|
+
return qarg_indices
|
217
|
+
|
218
|
+
def _update_carg_indices(self, carg):
|
219
|
+
"""
|
220
|
+
Change clbits indices of the current circuit node in order to
|
221
|
+
be comparable the indices of the template qubits list.
|
222
|
+
Args:
|
223
|
+
carg (list): list of clbits indices from the circuit for a given gate.
|
224
|
+
Returns:
|
225
|
+
list: circuit indices update for clbits.
|
226
|
+
"""
|
227
|
+
carg_indices = []
|
228
|
+
if carg:
|
229
|
+
for q in carg:
|
230
|
+
if q in self.clbits:
|
231
|
+
carg_indices.append(self.clbits.index(q))
|
232
|
+
if len(carg) != len(carg_indices):
|
233
|
+
carg_indices = []
|
234
|
+
return carg_indices
|
235
|
+
|
236
|
+
def _is_same_op(self, node_circuit, node_template):
|
237
|
+
"""
|
238
|
+
Check if two instructions are the same.
|
239
|
+
Args:
|
240
|
+
node_circuit (DAGDepNode): node in the circuit.
|
241
|
+
node_template (DAGDepNode): node in the template.
|
242
|
+
Returns:
|
243
|
+
bool: True if the same, False otherwise.
|
244
|
+
"""
|
245
|
+
return node_circuit.op.soft_compare(node_template.op)
|
246
|
+
|
247
|
+
def _is_same_q_conf(self, node_circuit, node_template, qarg_circuit):
|
248
|
+
"""
|
249
|
+
Check if the qubits configurations are compatible.
|
250
|
+
Args:
|
251
|
+
node_circuit (DAGDepNode): node in the circuit.
|
252
|
+
node_template (DAGDepNode): node in the template.
|
253
|
+
qarg_circuit (list): qubits configuration for the Instruction in the circuit.
|
254
|
+
Returns:
|
255
|
+
bool: True if possible, False otherwise.
|
256
|
+
"""
|
257
|
+
# If the gate is controlled, then the control qubits have to be compared as sets.
|
258
|
+
if isinstance(node_circuit.op, ControlledGate):
|
259
|
+
|
260
|
+
c_template = node_template.op.num_ctrl_qubits
|
261
|
+
|
262
|
+
if c_template == 1:
|
263
|
+
return qarg_circuit == node_template.qindices
|
264
|
+
|
265
|
+
else:
|
266
|
+
control_qubits_template = node_template.qindices[:c_template]
|
267
|
+
control_qubits_circuit = qarg_circuit[:c_template]
|
268
|
+
|
269
|
+
if set(control_qubits_circuit) == set(control_qubits_template):
|
270
|
+
|
271
|
+
target_qubits_template = node_template.qindices[c_template::]
|
272
|
+
target_qubits_circuit = qarg_circuit[c_template::]
|
273
|
+
|
274
|
+
if node_template.op.base_gate.name in [
|
275
|
+
"rxx",
|
276
|
+
"ryy",
|
277
|
+
"rzz",
|
278
|
+
"swap",
|
279
|
+
"iswap",
|
280
|
+
"ms",
|
281
|
+
]:
|
282
|
+
return set(target_qubits_template) == set(target_qubits_circuit)
|
283
|
+
else:
|
284
|
+
return target_qubits_template == target_qubits_circuit
|
285
|
+
else:
|
286
|
+
return False
|
287
|
+
# For non controlled gates, the qubits indices for symmetric gates can be compared as sets
|
288
|
+
# But for non-symmetric gates the qubits indices have to be compared as lists.
|
289
|
+
else:
|
290
|
+
if node_template.op.name in ["rxx", "ryy", "rzz", "swap", "iswap", "ms"]:
|
291
|
+
return set(qarg_circuit) == set(node_template.qindices)
|
292
|
+
else:
|
293
|
+
return qarg_circuit == node_template.qindices
|
294
|
+
|
295
|
+
def _is_same_c_conf(self, node_circuit, node_template, carg_circuit):
|
296
|
+
"""
|
297
|
+
Check if the clbits configurations are compatible.
|
298
|
+
Args:
|
299
|
+
node_circuit (DAGDepNode): node in the circuit.
|
300
|
+
node_template (DAGDepNode): node in the template.
|
301
|
+
carg_circuit (list): clbits configuration for the Instruction in the circuit.
|
302
|
+
Returns:
|
303
|
+
bool: True if possible, False otherwise.
|
304
|
+
"""
|
305
|
+
if (
|
306
|
+
node_circuit.type == "op"
|
307
|
+
and getattr(node_circuit.op, "_condition", None)
|
308
|
+
and node_template.type == "op"
|
309
|
+
and getattr(node_template.op, "_condition", None)
|
310
|
+
):
|
311
|
+
if set(carg_circuit) != set(node_template.cindices):
|
312
|
+
return False
|
313
|
+
if (
|
314
|
+
getattr(node_circuit.op, "_condition", None)[1]
|
315
|
+
!= getattr(node_template.op, "_condition", None)[1]
|
316
|
+
):
|
317
|
+
return False
|
318
|
+
return True
|
319
|
+
|
320
|
+
def _init_matched_blocked_list(self):
|
321
|
+
"""
|
322
|
+
Initialize the list of blocked and matchedwith attributes.
|
323
|
+
Returns:
|
324
|
+
Tuple[list, list, list, list]:
|
325
|
+
First list contains the attributes matchedwith in the circuit,
|
326
|
+
second list contains the attributes isblocked in the circuit,
|
327
|
+
third list contains the attributes matchedwith in the template,
|
328
|
+
fourth list contains the attributes isblocked in the template.
|
329
|
+
"""
|
330
|
+
circuit_matched = []
|
331
|
+
circuit_blocked = []
|
332
|
+
|
333
|
+
for node in self.circuit_dag_dep.get_nodes():
|
334
|
+
circuit_matched.append(node.matchedwith)
|
335
|
+
circuit_blocked.append(node.isblocked)
|
336
|
+
|
337
|
+
template_matched = []
|
338
|
+
template_blocked = []
|
339
|
+
|
340
|
+
for node in self.template_dag_dep.get_nodes():
|
341
|
+
template_matched.append(node.matchedwith)
|
342
|
+
template_blocked.append(node.isblocked)
|
343
|
+
|
344
|
+
return circuit_matched, circuit_blocked, template_matched, template_blocked
|
345
|
+
|
346
|
+
def _backward_heuristics(self, gate_indices, length, survivor):
|
347
|
+
"""
|
348
|
+
Heuristics to cut the tree in the backward match algorithm
|
349
|
+
Args:
|
350
|
+
gate_indices (list): list of candidates in the circuit.
|
351
|
+
length (int): depth for cutting the tree, cutting operation is repeated every length.
|
352
|
+
survivor (int): number of survivor branches.
|
353
|
+
"""
|
354
|
+
# Set the list of the counter for the different scenarios.
|
355
|
+
list_counter = []
|
356
|
+
|
357
|
+
for scenario in self.matching_list.matching_scenarios_list:
|
358
|
+
list_counter.append(scenario.counter)
|
359
|
+
|
360
|
+
metrics = []
|
361
|
+
# If all scenarios have the same counter and the counter is divisible by length.
|
362
|
+
if list_counter.count(list_counter[0]) == len(list_counter) and list_counter[0] <= len(
|
363
|
+
gate_indices
|
364
|
+
):
|
365
|
+
if (list_counter[0] - 1) % length == 0:
|
366
|
+
# The list metrics contains metric results for each scenarios.
|
367
|
+
for scenario in self.matching_list.matching_scenarios_list:
|
368
|
+
metrics.append(self._backward_metrics(scenario))
|
369
|
+
# Select only the scenarios with higher metrics for the given number of survivors.
|
370
|
+
largest = heapq.nlargest(survivor, range(len(metrics)), key=lambda x: metrics[x])
|
371
|
+
self.matching_list.matching_scenarios_list = [
|
372
|
+
i
|
373
|
+
for j, i in enumerate(self.matching_list.matching_scenarios_list)
|
374
|
+
if j in largest
|
375
|
+
]
|
376
|
+
|
377
|
+
def _backward_metrics(self, scenario):
|
378
|
+
"""
|
379
|
+
Heuristics to cut the tree in the backward match algorithm.
|
380
|
+
Args:
|
381
|
+
scenario (MatchingScenarios): scenario for the given match.
|
382
|
+
Returns:
|
383
|
+
int: length of the match for the given scenario.
|
384
|
+
"""
|
385
|
+
return len(scenario.matches)
|
386
|
+
|
387
|
+
def run_backward_match(self):
|
388
|
+
"""
|
389
|
+
Apply the forward match algorithm and returns the list of matches given an initial match
|
390
|
+
and a circuit qubits configuration.
|
391
|
+
|
392
|
+
"""
|
393
|
+
match_store_list = []
|
394
|
+
|
395
|
+
counter = 1
|
396
|
+
|
397
|
+
# Initialize the list of attributes matchedwith and isblocked.
|
398
|
+
(
|
399
|
+
circuit_matched,
|
400
|
+
circuit_blocked,
|
401
|
+
template_matched,
|
402
|
+
template_blocked,
|
403
|
+
) = self._init_matched_blocked_list()
|
404
|
+
|
405
|
+
# First Scenario is stored in the MatchingScenariosList().
|
406
|
+
first_match = MatchingScenarios(
|
407
|
+
circuit_matched,
|
408
|
+
circuit_blocked,
|
409
|
+
template_matched,
|
410
|
+
template_blocked,
|
411
|
+
self.forward_matches,
|
412
|
+
counter,
|
413
|
+
)
|
414
|
+
|
415
|
+
self.matching_list = MatchingScenariosList()
|
416
|
+
self.matching_list.append_scenario(first_match)
|
417
|
+
|
418
|
+
# Set the circuit indices that can be matched.
|
419
|
+
gate_indices = self._gate_indices()
|
420
|
+
|
421
|
+
number_of_gate_to_match = (
|
422
|
+
self.template_dag_dep.size() - (self.node_id_t - 1) - len(self.forward_matches)
|
423
|
+
)
|
424
|
+
|
425
|
+
# While the scenario stack is not empty.
|
426
|
+
while self.matching_list.matching_scenarios_list:
|
427
|
+
|
428
|
+
# If parameters are given, the heuristics is applied.
|
429
|
+
if self.heuristics_backward_param:
|
430
|
+
self._backward_heuristics(
|
431
|
+
gate_indices,
|
432
|
+
self.heuristics_backward_param[0],
|
433
|
+
self.heuristics_backward_param[1],
|
434
|
+
)
|
435
|
+
|
436
|
+
scenario = self.matching_list.pop_scenario()
|
437
|
+
|
438
|
+
circuit_matched = scenario.circuit_matched
|
439
|
+
circuit_blocked = scenario.circuit_blocked
|
440
|
+
template_matched = scenario.template_matched
|
441
|
+
template_blocked = scenario.template_blocked
|
442
|
+
matches_scenario = scenario.matches
|
443
|
+
counter_scenario = scenario.counter
|
444
|
+
|
445
|
+
# Part of the match list coming from the backward match.
|
446
|
+
match_backward = [
|
447
|
+
match for match in matches_scenario if match not in self.forward_matches
|
448
|
+
]
|
449
|
+
|
450
|
+
# Matches are stored if the counter is bigger than the length of the list of
|
451
|
+
# candidates in the circuit. Or if number of gate left to match is the same as
|
452
|
+
# the length of the backward part of the match.
|
453
|
+
if (
|
454
|
+
counter_scenario > len(gate_indices)
|
455
|
+
or len(match_backward) == number_of_gate_to_match
|
456
|
+
):
|
457
|
+
matches_scenario.sort(key=lambda x: x[0])
|
458
|
+
match_store_list.append(Match(matches_scenario, self.qubits, self.clbits))
|
459
|
+
continue
|
460
|
+
|
461
|
+
# First circuit candidate.
|
462
|
+
circuit_id = gate_indices[counter_scenario - 1]
|
463
|
+
node_circuit = self.circuit_dag_dep.get_node(circuit_id)
|
464
|
+
|
465
|
+
# If the circuit candidate is blocked, only the counter is changed.
|
466
|
+
if circuit_blocked[circuit_id]:
|
467
|
+
matching_scenario = MatchingScenarios(
|
468
|
+
circuit_matched,
|
469
|
+
circuit_blocked,
|
470
|
+
template_matched,
|
471
|
+
template_blocked,
|
472
|
+
matches_scenario,
|
473
|
+
counter_scenario + 1,
|
474
|
+
)
|
475
|
+
self.matching_list.append_scenario(matching_scenario)
|
476
|
+
continue
|
477
|
+
|
478
|
+
# The candidates in the template.
|
479
|
+
candidates_indices = self._find_backward_candidates(template_blocked, matches_scenario)
|
480
|
+
# Update of the qubits/clbits indices in the circuit in order to be
|
481
|
+
# comparable with the one in the template.
|
482
|
+
qarg1 = node_circuit.qindices
|
483
|
+
carg1 = node_circuit.cindices
|
484
|
+
|
485
|
+
qarg1 = self._update_qarg_indices(qarg1)
|
486
|
+
carg1 = self._update_carg_indices(carg1)
|
487
|
+
|
488
|
+
global_match = False
|
489
|
+
global_broken = []
|
490
|
+
|
491
|
+
# Loop over the template candidates.
|
492
|
+
for template_id in candidates_indices:
|
493
|
+
|
494
|
+
node_template = self.template_dag_dep.get_node(template_id)
|
495
|
+
qarg2 = self.template_dag_dep.get_node(template_id).qindices
|
496
|
+
|
497
|
+
# Necessary but not sufficient conditions for a match to happen.
|
498
|
+
if (
|
499
|
+
len(qarg1) != len(qarg2)
|
500
|
+
or set(qarg1) != set(qarg2)
|
501
|
+
or node_circuit.name != node_template.name
|
502
|
+
):
|
503
|
+
continue
|
504
|
+
|
505
|
+
# Check if the qubit, clbit configuration are compatible for a match,
|
506
|
+
# also check if the operation are the same.
|
507
|
+
if (
|
508
|
+
self._is_same_q_conf(node_circuit, node_template, qarg1)
|
509
|
+
and self._is_same_c_conf(node_circuit, node_template, carg1)
|
510
|
+
and self._is_same_op(node_circuit, node_template)
|
511
|
+
):
|
512
|
+
|
513
|
+
# If there is a match the attributes are copied.
|
514
|
+
circuit_matched_match = circuit_matched.copy()
|
515
|
+
circuit_blocked_match = circuit_blocked.copy()
|
516
|
+
|
517
|
+
template_matched_match = template_matched.copy()
|
518
|
+
template_blocked_match = template_blocked.copy()
|
519
|
+
|
520
|
+
matches_scenario_match = matches_scenario.copy()
|
521
|
+
|
522
|
+
block_list = []
|
523
|
+
broken_matches_match = []
|
524
|
+
|
525
|
+
# Loop to check if the match is not connected, in this case
|
526
|
+
# the successors matches are blocked and unmatched.
|
527
|
+
for potential_block in self.template_dag_dep.successors(template_id):
|
528
|
+
if not template_matched_match[potential_block]:
|
529
|
+
template_blocked_match[potential_block] = True
|
530
|
+
block_list.append(potential_block)
|
531
|
+
for block_id in block_list:
|
532
|
+
for succ_id in self.template_dag_dep.successors(block_id):
|
533
|
+
template_blocked_match[succ_id] = True
|
534
|
+
if template_matched_match[succ_id]:
|
535
|
+
new_id = template_matched_match[succ_id][0]
|
536
|
+
circuit_matched_match[new_id] = []
|
537
|
+
template_matched_match[succ_id] = []
|
538
|
+
broken_matches_match.append(succ_id)
|
539
|
+
|
540
|
+
if broken_matches_match:
|
541
|
+
global_broken.append(True)
|
542
|
+
else:
|
543
|
+
global_broken.append(False)
|
544
|
+
|
545
|
+
new_matches_scenario_match = [
|
546
|
+
elem
|
547
|
+
for elem in matches_scenario_match
|
548
|
+
if elem[0] not in broken_matches_match
|
549
|
+
]
|
550
|
+
|
551
|
+
condition = True
|
552
|
+
|
553
|
+
for back_match in match_backward:
|
554
|
+
if back_match not in new_matches_scenario_match:
|
555
|
+
condition = False
|
556
|
+
break
|
557
|
+
|
558
|
+
# First option greedy match.
|
559
|
+
if ([self.node_id_t, self.node_id_c] in new_matches_scenario_match) and (
|
560
|
+
condition or not match_backward
|
561
|
+
):
|
562
|
+
template_matched_match[template_id] = [circuit_id]
|
563
|
+
circuit_matched_match[circuit_id] = [template_id]
|
564
|
+
new_matches_scenario_match.append([template_id, circuit_id])
|
565
|
+
|
566
|
+
new_matching_scenario = MatchingScenarios(
|
567
|
+
circuit_matched_match,
|
568
|
+
circuit_blocked_match,
|
569
|
+
template_matched_match,
|
570
|
+
template_blocked_match,
|
571
|
+
new_matches_scenario_match,
|
572
|
+
counter_scenario + 1,
|
573
|
+
)
|
574
|
+
self.matching_list.append_scenario(new_matching_scenario)
|
575
|
+
|
576
|
+
global_match = True
|
577
|
+
|
578
|
+
if global_match:
|
579
|
+
circuit_matched_block_s = circuit_matched.copy()
|
580
|
+
circuit_blocked_block_s = circuit_blocked.copy()
|
581
|
+
|
582
|
+
template_matched_block_s = template_matched.copy()
|
583
|
+
template_blocked_block_s = template_blocked.copy()
|
584
|
+
|
585
|
+
matches_scenario_block_s = matches_scenario.copy()
|
586
|
+
|
587
|
+
circuit_blocked_block_s[circuit_id] = True
|
588
|
+
|
589
|
+
broken_matches = []
|
590
|
+
|
591
|
+
# Second option, not a greedy match, block all successors (push the gate
|
592
|
+
# to the right).
|
593
|
+
for succ in self.circuit_dag_dep.get_node(circuit_id).successors:
|
594
|
+
circuit_blocked_block_s[succ] = True
|
595
|
+
if circuit_matched_block_s[succ]:
|
596
|
+
broken_matches.append(succ)
|
597
|
+
new_id = circuit_matched_block_s[succ][0]
|
598
|
+
template_matched_block_s[new_id] = []
|
599
|
+
circuit_matched_block_s[succ] = []
|
600
|
+
|
601
|
+
new_matches_scenario_block_s = [
|
602
|
+
elem for elem in matches_scenario_block_s if elem[1] not in broken_matches
|
603
|
+
]
|
604
|
+
|
605
|
+
condition_not_greedy = True
|
606
|
+
|
607
|
+
for back_match in match_backward:
|
608
|
+
if back_match not in new_matches_scenario_block_s:
|
609
|
+
condition_not_greedy = False
|
610
|
+
break
|
611
|
+
|
612
|
+
if ([self.node_id_t, self.node_id_c] in new_matches_scenario_block_s) and (
|
613
|
+
condition_not_greedy or not match_backward
|
614
|
+
):
|
615
|
+
new_matching_scenario = MatchingScenarios(
|
616
|
+
circuit_matched_block_s,
|
617
|
+
circuit_blocked_block_s,
|
618
|
+
template_matched_block_s,
|
619
|
+
template_blocked_block_s,
|
620
|
+
new_matches_scenario_block_s,
|
621
|
+
counter_scenario + 1,
|
622
|
+
)
|
623
|
+
self.matching_list.append_scenario(new_matching_scenario)
|
624
|
+
|
625
|
+
# Third option: if blocking the successors breaks a match, we consider
|
626
|
+
# also the possibility to block all predecessors (push the gate to the left).
|
627
|
+
if broken_matches and all(global_broken):
|
628
|
+
|
629
|
+
circuit_matched_block_p = circuit_matched.copy()
|
630
|
+
circuit_blocked_block_p = circuit_blocked.copy()
|
631
|
+
|
632
|
+
template_matched_block_p = template_matched.copy()
|
633
|
+
template_blocked_block_p = template_blocked.copy()
|
634
|
+
|
635
|
+
matches_scenario_block_p = matches_scenario.copy()
|
636
|
+
|
637
|
+
circuit_blocked_block_p[circuit_id] = True
|
638
|
+
|
639
|
+
for pred in self.circuit_dag_dep.get_node(circuit_id).predecessors:
|
640
|
+
circuit_blocked_block_p[pred] = True
|
641
|
+
|
642
|
+
matching_scenario = MatchingScenarios(
|
643
|
+
circuit_matched_block_p,
|
644
|
+
circuit_blocked_block_p,
|
645
|
+
template_matched_block_p,
|
646
|
+
template_blocked_block_p,
|
647
|
+
matches_scenario_block_p,
|
648
|
+
counter_scenario + 1,
|
649
|
+
)
|
650
|
+
self.matching_list.append_scenario(matching_scenario)
|
651
|
+
|
652
|
+
# If there is no match then there are three options.
|
653
|
+
if not global_match:
|
654
|
+
|
655
|
+
circuit_blocked[circuit_id] = True
|
656
|
+
|
657
|
+
following_matches = []
|
658
|
+
|
659
|
+
successors = self.circuit_dag_dep.get_node(circuit_id).successors
|
660
|
+
for succ in successors:
|
661
|
+
if circuit_matched[succ]:
|
662
|
+
following_matches.append(succ)
|
663
|
+
|
664
|
+
# First option, the circuit gate is not disturbing because there are no
|
665
|
+
# following match and no predecessors.
|
666
|
+
predecessors = self.circuit_dag_dep.get_node(circuit_id).predecessors
|
667
|
+
|
668
|
+
if not predecessors or not following_matches:
|
669
|
+
|
670
|
+
matching_scenario = MatchingScenarios(
|
671
|
+
circuit_matched,
|
672
|
+
circuit_blocked,
|
673
|
+
template_matched,
|
674
|
+
template_blocked,
|
675
|
+
matches_scenario,
|
676
|
+
counter_scenario + 1,
|
677
|
+
)
|
678
|
+
self.matching_list.append_scenario(matching_scenario)
|
679
|
+
|
680
|
+
else:
|
681
|
+
|
682
|
+
circuit_matched_nomatch = circuit_matched.copy()
|
683
|
+
circuit_blocked_nomatch = circuit_blocked.copy()
|
684
|
+
|
685
|
+
template_matched_nomatch = template_matched.copy()
|
686
|
+
template_blocked_nomatch = template_blocked.copy()
|
687
|
+
|
688
|
+
matches_scenario_nomatch = matches_scenario.copy()
|
689
|
+
|
690
|
+
# Second option, all predecessors are blocked (circuit gate is
|
691
|
+
# moved to the left).
|
692
|
+
for pred in predecessors:
|
693
|
+
circuit_blocked[pred] = True
|
694
|
+
|
695
|
+
matching_scenario = MatchingScenarios(
|
696
|
+
circuit_matched,
|
697
|
+
circuit_blocked,
|
698
|
+
template_matched,
|
699
|
+
template_blocked,
|
700
|
+
matches_scenario,
|
701
|
+
counter_scenario + 1,
|
702
|
+
)
|
703
|
+
self.matching_list.append_scenario(matching_scenario)
|
704
|
+
|
705
|
+
# Third option, all successors are blocked (circuit gate is
|
706
|
+
# moved to the right).
|
707
|
+
|
708
|
+
broken_matches = []
|
709
|
+
|
710
|
+
successors = self.circuit_dag_dep.get_node(circuit_id).successors
|
711
|
+
|
712
|
+
for succ in successors:
|
713
|
+
circuit_blocked_nomatch[succ] = True
|
714
|
+
if circuit_matched_nomatch[succ]:
|
715
|
+
broken_matches.append(succ)
|
716
|
+
circuit_matched_nomatch[succ] = []
|
717
|
+
|
718
|
+
new_matches_scenario_nomatch = [
|
719
|
+
elem for elem in matches_scenario_nomatch if elem[1] not in broken_matches
|
720
|
+
]
|
721
|
+
|
722
|
+
condition_block = True
|
723
|
+
|
724
|
+
for back_match in match_backward:
|
725
|
+
if back_match not in new_matches_scenario_nomatch:
|
726
|
+
condition_block = False
|
727
|
+
break
|
728
|
+
|
729
|
+
if ([self.node_id_t, self.node_id_c] in matches_scenario_nomatch) and (
|
730
|
+
condition_block or not match_backward
|
731
|
+
):
|
732
|
+
new_matching_scenario = MatchingScenarios(
|
733
|
+
circuit_matched_nomatch,
|
734
|
+
circuit_blocked_nomatch,
|
735
|
+
template_matched_nomatch,
|
736
|
+
template_blocked_nomatch,
|
737
|
+
new_matches_scenario_nomatch,
|
738
|
+
counter_scenario + 1,
|
739
|
+
)
|
740
|
+
self.matching_list.append_scenario(new_matching_scenario)
|
741
|
+
|
742
|
+
length = max(len(m.match) for m in match_store_list)
|
743
|
+
|
744
|
+
# Store the matches with maximal length.
|
745
|
+
for scenario in match_store_list:
|
746
|
+
if (len(scenario.match) == length) and not any(
|
747
|
+
scenario.match == x.match for x in self.match_final
|
748
|
+
):
|
749
|
+
self.match_final.append(scenario)
|