qiskit 2.1.0rc1__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 +159 -0
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/_numpy_compat.py +73 -0
- qiskit/circuit/__init__.py +1335 -0
- qiskit/circuit/_add_control.py +338 -0
- qiskit/circuit/_classical_resource_map.py +154 -0
- qiskit/circuit/_standard_gates_commutations.py +3849 -0
- qiskit/circuit/_utils.py +167 -0
- qiskit/circuit/annotated_operation.py +279 -0
- qiskit/circuit/annotation.py +404 -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 +156 -0
- qiskit/circuit/classical/expr/visitors.py +381 -0
- qiskit/circuit/classical/types/__init__.py +113 -0
- qiskit/circuit/classical/types/ordering.py +229 -0
- qiskit/circuit/classical/types/types.py +30 -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 +188 -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 +159 -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 +506 -0
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +395 -0
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +501 -0
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +389 -0
- qiskit/circuit/library/arithmetic/quadratic_form.py +370 -0
- qiskit/circuit/library/arithmetic/weighted_adder.py +428 -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 +322 -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 +163 -0
- qiskit/circuit/library/generalized_gates/gms.py +179 -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 +202 -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 +236 -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 +301 -0
- qiskit/circuit/library/n_local/n_local.py +1478 -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 +202 -0
- qiskit/circuit/library/phase_estimation.py +177 -0
- qiskit/circuit/library/phase_oracle.py +239 -0
- qiskit/circuit/library/quantum_volume.py +179 -0
- qiskit/circuit/library/standard_gates/__init__.py +141 -0
- qiskit/circuit/library/standard_gates/dcx.py +76 -0
- qiskit/circuit/library/standard_gates/ecr.py +126 -0
- qiskit/circuit/library/standard_gates/equivalence_library.py +1936 -0
- qiskit/circuit/library/standard_gates/global_phase.py +83 -0
- qiskit/circuit/library/standard_gates/h.py +230 -0
- qiskit/circuit/library/standard_gates/i.py +76 -0
- qiskit/circuit/library/standard_gates/iswap.py +115 -0
- qiskit/circuit/library/standard_gates/p.py +415 -0
- qiskit/circuit/library/standard_gates/r.py +108 -0
- qiskit/circuit/library/standard_gates/rx.py +269 -0
- qiskit/circuit/library/standard_gates/rxx.py +165 -0
- qiskit/circuit/library/standard_gates/ry.py +268 -0
- qiskit/circuit/library/standard_gates/ryy.py +165 -0
- qiskit/circuit/library/standard_gates/rz.py +290 -0
- qiskit/circuit/library/standard_gates/rzx.py +211 -0
- qiskit/circuit/library/standard_gates/rzz.py +181 -0
- qiskit/circuit/library/standard_gates/s.py +424 -0
- qiskit/circuit/library/standard_gates/swap.py +268 -0
- qiskit/circuit/library/standard_gates/sx.py +303 -0
- qiskit/circuit/library/standard_gates/t.py +169 -0
- qiskit/circuit/library/standard_gates/u.py +379 -0
- qiskit/circuit/library/standard_gates/u1.py +466 -0
- qiskit/circuit/library/standard_gates/u2.py +145 -0
- qiskit/circuit/library/standard_gates/u3.py +412 -0
- qiskit/circuit/library/standard_gates/x.py +1335 -0
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +164 -0
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +197 -0
- qiskit/circuit/library/standard_gates/y.py +253 -0
- qiskit/circuit/library/standard_gates/z.py +331 -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 +188 -0
- qiskit/circuit/parameterexpression.py +737 -0
- qiskit/circuit/parametertable.py +119 -0
- qiskit/circuit/parametervector.py +140 -0
- qiskit/circuit/quantumcircuit.py +7610 -0
- qiskit/circuit/quantumcircuitdata.py +137 -0
- qiskit/circuit/random/__init__.py +50 -0
- qiskit/circuit/random/utils.py +755 -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 +185 -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 +44 -0
- qiskit/dagcircuit/collect_blocks.py +403 -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 +193 -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 +172 -0
- qiskit/primitives/containers/estimator_pub.py +222 -0
- qiskit/primitives/containers/object_array.py +94 -0
- qiskit/primitives/containers/observables_array.py +380 -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 +100 -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 +376 -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 +466 -0
- qiskit/qasm3/ast.py +796 -0
- qiskit/qasm3/exceptions.py +27 -0
- qiskit/qasm3/experimental.py +70 -0
- qiskit/qasm3/exporter.py +1363 -0
- qiskit/qasm3/printer.py +620 -0
- qiskit/qpy/__init__.py +2141 -0
- qiskit/qpy/binary_io/__init__.py +35 -0
- qiskit/qpy/binary_io/circuits.py +1687 -0
- qiskit/qpy/binary_io/parse_sympy_repr.py +126 -0
- qiskit/qpy/binary_io/schedules.py +288 -0
- qiskit/qpy/binary_io/value.py +1183 -0
- qiskit/qpy/common.py +361 -0
- qiskit/qpy/exceptions.py +53 -0
- qiskit/qpy/formats.py +458 -0
- qiskit/qpy/interface.py +384 -0
- qiskit/qpy/type_keys.py +415 -0
- qiskit/quantum_info/__init__.py +172 -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 +29 -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 +24 -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 +584 -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 +76 -0
- qiskit/result/utils.py +294 -0
- qiskit/synthesis/__init__.py +250 -0
- qiskit/synthesis/arithmetic/__init__.py +18 -0
- qiskit/synthesis/arithmetic/adders/__init__.py +18 -0
- qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +154 -0
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +107 -0
- qiskit/synthesis/arithmetic/adders/rv_ripple_carry_adder.py +156 -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/generate_basis_approximations.py +53 -0
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +280 -0
- qiskit/synthesis/evolution/__init__.py +21 -0
- qiskit/synthesis/evolution/evolution_synthesis.py +48 -0
- qiskit/synthesis/evolution/lie_trotter.py +123 -0
- qiskit/synthesis/evolution/matrix_synthesis.py +47 -0
- qiskit/synthesis/evolution/pauli_network.py +80 -0
- qiskit/synthesis/evolution/product_formula.py +316 -0
- qiskit/synthesis/evolution/qdrift.py +133 -0
- qiskit/synthesis/evolution/suzuki_trotter.py +227 -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 +29 -0
- qiskit/synthesis/multi_controlled/mcmt_vchain.py +52 -0
- qiskit/synthesis/multi_controlled/mcx_synthesis.py +583 -0
- qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +205 -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 +61 -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 +359 -0
- qiskit/transpiler/__init__.py +1352 -0
- qiskit/transpiler/basepasses.py +190 -0
- qiskit/transpiler/coupling.py +500 -0
- qiskit/transpiler/exceptions.py +59 -0
- qiskit/transpiler/instruction_durations.py +263 -0
- qiskit/transpiler/layout.py +740 -0
- qiskit/transpiler/passes/__init__.py +278 -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 +197 -0
- qiskit/transpiler/passes/layout/disjoint_utils.py +54 -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 +525 -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 +292 -0
- qiskit/transpiler/passes/layout/vf2_post_layout.py +376 -0
- qiskit/transpiler/passes/layout/vf2_utils.py +245 -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 +251 -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_clifford_t.py +68 -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 +633 -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 +465 -0
- qiskit/transpiler/passes/routing/star_prerouting.py +433 -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 +17 -0
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +284 -0
- qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py +876 -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 +21 -0
- qiskit/transpiler/passes/synthesis/aqc_plugin.py +153 -0
- qiskit/transpiler/passes/synthesis/clifford_unitary_synth_plugin.py +123 -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 +2338 -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 +318 -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 +154 -0
- qiskit/transpiler/preset_passmanagers/__init__.py +93 -0
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +1114 -0
- qiskit/transpiler/preset_passmanagers/common.py +773 -0
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +443 -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 +355 -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 +677 -0
- qiskit/visualization/circuit/circuit_visualization.py +735 -0
- qiskit/visualization/circuit/latex.py +668 -0
- qiskit/visualization/circuit/matplotlib.py +2041 -0
- qiskit/visualization/circuit/qcstyle.py +130 -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/__init__.py +13 -0
- qiskit/visualization/dag/dagstyle.py +103 -0
- qiskit/visualization/dag/styles/__init__.py +13 -0
- qiskit/visualization/dag/styles/color.json +10 -0
- qiskit/visualization/dag/styles/plain.json +5 -0
- qiskit/visualization/dag_visualization.py +389 -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/style.py +223 -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.1.0rc1.dist-info/METADATA +221 -0
- qiskit-2.1.0rc1.dist-info/RECORD +699 -0
- qiskit-2.1.0rc1.dist-info/WHEEL +6 -0
- qiskit-2.1.0rc1.dist-info/entry_points.txt +88 -0
- qiskit-2.1.0rc1.dist-info/licenses/LICENSE.txt +203 -0
- qiskit-2.1.0rc1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2025
|
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
|
+
"""Contract control-flow operations that contain idle wires."""
|
14
|
+
|
15
|
+
from qiskit.circuit import Qubit, Clbit, QuantumCircuit
|
16
|
+
from qiskit.dagcircuit import DAGCircuit, DAGOpNode
|
17
|
+
from qiskit.transpiler.basepasses import TransformationPass
|
18
|
+
|
19
|
+
|
20
|
+
class ContractIdleWiresInControlFlow(TransformationPass):
|
21
|
+
"""Remove idle qubits from control-flow operations of a :class:`.DAGCircuit`."""
|
22
|
+
|
23
|
+
def run(self, dag):
|
24
|
+
# `control_flow_op_nodes` is eager and doesn't borrow; we're mutating the DAG in the loop.
|
25
|
+
for node in dag.control_flow_op_nodes() or []:
|
26
|
+
inst = node._to_circuit_instruction()
|
27
|
+
new_inst = _contract_control_flow(inst)
|
28
|
+
if new_inst is inst:
|
29
|
+
# No top-level contraction; nothing to do.
|
30
|
+
continue
|
31
|
+
replacement = DAGCircuit()
|
32
|
+
# Dictionaries to retain insertion order for reproducibility, and because we can
|
33
|
+
# then re-use them as mapping dictionaries.
|
34
|
+
qubits, clbits, vars_ = {}, {}, {}
|
35
|
+
for _, _, wire in dag.edges(node):
|
36
|
+
if isinstance(wire, Qubit):
|
37
|
+
qubits[wire] = wire
|
38
|
+
elif isinstance(wire, Clbit):
|
39
|
+
clbits[wire] = wire
|
40
|
+
else:
|
41
|
+
vars_[wire] = wire
|
42
|
+
replacement.add_qubits(list(qubits))
|
43
|
+
replacement.add_clbits(list(clbits))
|
44
|
+
for var in vars_:
|
45
|
+
replacement.add_captured_var(var)
|
46
|
+
replacement._apply_op_node_back(DAGOpNode.from_instruction(new_inst))
|
47
|
+
# The replacement DAG is defined over all the same qubits, but with the correct
|
48
|
+
# qubits now explicitly marked as idle, so everything gets linked up correctly.
|
49
|
+
dag.substitute_node_with_dag(node, replacement, wires=qubits | clbits | vars_)
|
50
|
+
return dag
|
51
|
+
|
52
|
+
|
53
|
+
def _contract_control_flow(inst):
|
54
|
+
"""Contract a `CircuitInstruction` containing a control-flow operation.
|
55
|
+
|
56
|
+
Returns the input object by the same reference if there's no contraction to be done at the call
|
57
|
+
site, though nested control-flow ops may have been contracted in place."""
|
58
|
+
op = inst.operation
|
59
|
+
idle = set(inst.qubits)
|
60
|
+
for block in op.blocks:
|
61
|
+
qubit_map = dict(zip(block.qubits, inst.qubits))
|
62
|
+
for i, inner in enumerate(block.data):
|
63
|
+
if inner.is_control_flow():
|
64
|
+
# In `QuantumCircuit` it's easy to replace an instruction with a narrower one, so it
|
65
|
+
# doesn't matter much if this is replacing it with itself.
|
66
|
+
block.data[i] = inner = _contract_control_flow(inner)
|
67
|
+
for qubit in inner.qubits:
|
68
|
+
idle.discard(qubit_map[qubit])
|
69
|
+
# If a box, we still want the prior side-effect of contracting any internal control-flow
|
70
|
+
# operations (optimisations are still valid _within_ a box), but we don't want to contract the
|
71
|
+
# box itself. If there's no idle qubits, we're also done here.
|
72
|
+
if not idle or inst.name == "box":
|
73
|
+
return inst
|
74
|
+
|
75
|
+
def contract(block):
|
76
|
+
out = QuantumCircuit(
|
77
|
+
name=block.name,
|
78
|
+
global_phase=block.global_phase,
|
79
|
+
metadata=block.metadata,
|
80
|
+
captures=block.iter_captures(),
|
81
|
+
)
|
82
|
+
out.add_bits(
|
83
|
+
[
|
84
|
+
block_qubit
|
85
|
+
for (block_qubit, inst_qubit) in zip(block.qubits, inst.qubits)
|
86
|
+
if inst_qubit not in idle
|
87
|
+
]
|
88
|
+
)
|
89
|
+
out.add_bits(block.clbits)
|
90
|
+
for creg in block.cregs:
|
91
|
+
out.add_register(creg)
|
92
|
+
# Control-flow ops can only have captures and locals, and we already added the captures.
|
93
|
+
for var in block.iter_declared_vars():
|
94
|
+
out.add_uninitialized_var(var)
|
95
|
+
for stretch in block.iter_declared_stretches():
|
96
|
+
out.add_stretch(stretch)
|
97
|
+
for inner in block:
|
98
|
+
out._append(inner)
|
99
|
+
return out
|
100
|
+
|
101
|
+
return inst.replace(
|
102
|
+
operation=op.replace_blocks(contract(block) for block in op.blocks),
|
103
|
+
qubits=[qubit for qubit in inst.qubits if qubit not in idle],
|
104
|
+
)
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2023
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
|
14
|
+
"""Remove any swap gates in the circuit by pushing it through into a qubit permutation."""
|
15
|
+
|
16
|
+
import logging
|
17
|
+
|
18
|
+
from qiskit.transpiler.basepasses import TransformationPass
|
19
|
+
from qiskit.transpiler.layout import Layout
|
20
|
+
from qiskit._accelerate import elide_permutations as elide_permutations_rs
|
21
|
+
|
22
|
+
logger = logging.getLogger(__name__)
|
23
|
+
|
24
|
+
|
25
|
+
class ElidePermutations(TransformationPass):
|
26
|
+
r"""Remove permutation operations from a pre-layout circuit
|
27
|
+
|
28
|
+
This pass is intended to be run before a layout (mapping virtual qubits
|
29
|
+
to physical qubits) is set during the transpilation pipeline. This
|
30
|
+
pass iterates over the :class:`~.DAGCircuit` and when a :class:`~.SwapGate`
|
31
|
+
or :class:`~.PermutationGate` are encountered it permutes the virtual qubits in
|
32
|
+
the circuit and removes the swap gate. This will effectively remove any
|
33
|
+
:class:`~SwapGate`\s or :class:`~PermutationGate` in the circuit prior to running
|
34
|
+
layout. If this pass is run after a layout has been set it will become a no-op
|
35
|
+
(and log a warning) as this optimization is not sound after physical qubits are
|
36
|
+
selected and there are connectivity constraints to adhere to.
|
37
|
+
|
38
|
+
For tracking purposes this pass sets 3 values in the property set if there
|
39
|
+
are any :class:`~.SwapGate` or :class:`~.PermutationGate` objects in the circuit
|
40
|
+
and the pass isn't a no-op.
|
41
|
+
|
42
|
+
* ``original_layout``: The trivial :class:`~.Layout` for the input to this pass being run
|
43
|
+
* ``original_qubit_indices``: The mapping of qubit objects to positional indices for the state
|
44
|
+
of the circuit as input to this pass.
|
45
|
+
* ``virtual_permutation_layout``: A :class:`~.Layout` object mapping input qubits to the output
|
46
|
+
state after eliding permutations.
|
47
|
+
|
48
|
+
These three properties are needed for the transpiler to track the permutations in the out
|
49
|
+
:attr:`.QuantumCircuit.layout` attribute. The elision of permutations is equivalent to a
|
50
|
+
``final_layout`` set by routing and all three of these attributes are needed in the case
|
51
|
+
"""
|
52
|
+
|
53
|
+
def run(self, dag):
|
54
|
+
"""Run the ElidePermutations pass on ``dag``.
|
55
|
+
|
56
|
+
Args:
|
57
|
+
dag (DAGCircuit): the DAG to be optimized.
|
58
|
+
|
59
|
+
Returns:
|
60
|
+
DAGCircuit: the optimized DAG.
|
61
|
+
"""
|
62
|
+
if self.property_set["layout"] is not None:
|
63
|
+
logger.warning(
|
64
|
+
"ElidePermutations is not valid after a layout has been set. This indicates "
|
65
|
+
"an invalid pass manager construction."
|
66
|
+
)
|
67
|
+
return dag
|
68
|
+
|
69
|
+
result = elide_permutations_rs.run(dag)
|
70
|
+
|
71
|
+
# If the pass did not do anything, the result is None
|
72
|
+
if result is None:
|
73
|
+
return dag
|
74
|
+
|
75
|
+
# Otherwise, the result is a pair consisting of the rewritten DAGCircuit and the
|
76
|
+
# qubit mapping.
|
77
|
+
(new_dag, qubit_mapping) = result
|
78
|
+
|
79
|
+
input_qubit_mapping = {qubit: index for index, qubit in enumerate(dag.qubits)}
|
80
|
+
self.property_set["original_layout"] = Layout(input_qubit_mapping)
|
81
|
+
if self.property_set["original_qubit_indices"] is None:
|
82
|
+
self.property_set["original_qubit_indices"] = input_qubit_mapping
|
83
|
+
|
84
|
+
new_layout = Layout({dag.qubits[out]: idx for idx, out in enumerate(qubit_mapping)})
|
85
|
+
if current_layout := self.property_set["virtual_permutation_layout"]:
|
86
|
+
self.property_set["virtual_permutation_layout"] = new_layout.compose(
|
87
|
+
current_layout.inverse(dag.qubits, dag.qubits), dag.qubits
|
88
|
+
)
|
89
|
+
else:
|
90
|
+
self.property_set["virtual_permutation_layout"] = new_layout
|
91
|
+
return new_dag
|
@@ -0,0 +1,420 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2019.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""Pass for Hoare logic circuit optimization."""
|
14
|
+
from qiskit.transpiler.basepasses import TransformationPass
|
15
|
+
from qiskit.circuit import QuantumRegister, ControlledGate, Gate
|
16
|
+
from qiskit.dagcircuit import DAGCircuit
|
17
|
+
from qiskit.circuit.library import UnitaryGate
|
18
|
+
from qiskit.quantum_info.operators.predicates import matrix_equal
|
19
|
+
from qiskit.circuit.exceptions import CircuitError
|
20
|
+
from qiskit.circuit.library.standard_gates import CZGate, CU1Gate, MCU1Gate
|
21
|
+
from qiskit.utils import optionals as _optionals
|
22
|
+
|
23
|
+
|
24
|
+
@_optionals.HAS_Z3.require_in_instance
|
25
|
+
class HoareOptimizer(TransformationPass):
|
26
|
+
"""This is a transpiler pass using Hoare logic circuit optimization.
|
27
|
+
The inner workings of this are detailed in:
|
28
|
+
https://arxiv.org/abs/1810.00375
|
29
|
+
"""
|
30
|
+
|
31
|
+
def __init__(self, size=10):
|
32
|
+
"""
|
33
|
+
Args:
|
34
|
+
size (int): size of gate cache, in number of gates
|
35
|
+
Raises:
|
36
|
+
MissingOptionalLibraryError: if unable to import z3 solver
|
37
|
+
"""
|
38
|
+
# This module is just a script that adds several post conditions onto existing classes.
|
39
|
+
from . import _gate_extension
|
40
|
+
|
41
|
+
super().__init__()
|
42
|
+
self.solver = None
|
43
|
+
self.variables = None
|
44
|
+
self.gatenum = None
|
45
|
+
self.gatecache = None
|
46
|
+
self.varnum = None
|
47
|
+
self.size = size
|
48
|
+
|
49
|
+
def _gen_variable(self, qubit):
|
50
|
+
"""After each gate generate a new unique variable name for each of the
|
51
|
+
qubits, using scheme: 'q[id]_[gatenum]', e.g. q1_0 -> q1_1 -> q1_2,
|
52
|
+
q2_0 -> q2_1
|
53
|
+
Args:
|
54
|
+
qubit (Qubit): qubit to generate new variable for
|
55
|
+
Returns:
|
56
|
+
BoolRef: z3 variable of qubit state
|
57
|
+
"""
|
58
|
+
import z3
|
59
|
+
|
60
|
+
varname = "q" + str(qubit) + "_" + str(self.gatenum[qubit])
|
61
|
+
var = z3.Bool(varname)
|
62
|
+
self.gatenum[qubit] += 1
|
63
|
+
self.variables[qubit].append(var)
|
64
|
+
return var
|
65
|
+
|
66
|
+
def _initialize(self, dag):
|
67
|
+
"""create boolean variables for each qubit and apply qb == 0 condition
|
68
|
+
Args:
|
69
|
+
dag (DAGCircuit): input DAG to get qubits from
|
70
|
+
"""
|
71
|
+
import z3
|
72
|
+
|
73
|
+
for qbt in dag.qubits:
|
74
|
+
self.gatenum[qbt] = 0
|
75
|
+
self.variables[qbt] = []
|
76
|
+
self.gatecache[qbt] = []
|
77
|
+
self.varnum[qbt] = {}
|
78
|
+
x = self._gen_variable(qbt)
|
79
|
+
self.solver.add(z3.Not(x))
|
80
|
+
|
81
|
+
def _add_postconditions(self, gate, ctrl_ones, trgtqb, trgtvar):
|
82
|
+
"""create boolean variables for each qubit the gate is applied to
|
83
|
+
and apply the relevant post conditions.
|
84
|
+
a gate rotating out of the z-basis will not have any valid
|
85
|
+
post-conditions, in which case the qubit state is unknown
|
86
|
+
Args:
|
87
|
+
gate (Gate): gate to inspect
|
88
|
+
ctrl_ones (BoolRef): z3 condition asserting all control qubits to 1
|
89
|
+
trgtqb (list((QuantumRegister, int))): list of target qubits
|
90
|
+
trgtvar (list(BoolRef)): z3 variables corresponding to latest state
|
91
|
+
of target qubits
|
92
|
+
"""
|
93
|
+
import z3
|
94
|
+
|
95
|
+
new_vars = []
|
96
|
+
for qbt in trgtqb:
|
97
|
+
new_vars.append(self._gen_variable(qbt))
|
98
|
+
|
99
|
+
try:
|
100
|
+
self.solver.add(z3.Implies(ctrl_ones, gate._postconditions(*(trgtvar + new_vars))))
|
101
|
+
except AttributeError:
|
102
|
+
pass
|
103
|
+
|
104
|
+
for i, tvar in enumerate(trgtvar):
|
105
|
+
self.solver.add(z3.Implies(z3.Not(ctrl_ones), new_vars[i] == tvar))
|
106
|
+
|
107
|
+
def _test_gate(self, gate, ctrl_ones, trgtvar):
|
108
|
+
"""use z3 sat solver to determine triviality of gate
|
109
|
+
Args:
|
110
|
+
gate (Gate): gate to inspect
|
111
|
+
ctrl_ones (BoolRef): z3 condition asserting all control qubits to 1
|
112
|
+
trgtvar (list(BoolRef)): z3 variables corresponding to latest state
|
113
|
+
of target qubits
|
114
|
+
Returns:
|
115
|
+
bool: if gate is trivial
|
116
|
+
"""
|
117
|
+
import z3
|
118
|
+
|
119
|
+
trivial = False
|
120
|
+
self.solver.push()
|
121
|
+
|
122
|
+
try:
|
123
|
+
triv_cond = gate._trivial_if(*trgtvar)
|
124
|
+
except AttributeError:
|
125
|
+
self.solver.add(ctrl_ones)
|
126
|
+
trivial = self.solver.check() == z3.unsat
|
127
|
+
else:
|
128
|
+
if isinstance(triv_cond, bool):
|
129
|
+
if triv_cond and len(trgtvar) == 1:
|
130
|
+
self.solver.add(z3.Not(z3.And(ctrl_ones, trgtvar[0])))
|
131
|
+
sol1 = self.solver.check() == z3.unsat
|
132
|
+
self.solver.pop()
|
133
|
+
self.solver.push()
|
134
|
+
self.solver.add(z3.And(ctrl_ones, trgtvar[0]))
|
135
|
+
sol2 = self.solver.check() == z3.unsat
|
136
|
+
trivial = sol1 or sol2
|
137
|
+
else:
|
138
|
+
self.solver.add(z3.And(ctrl_ones, z3.Not(triv_cond)))
|
139
|
+
trivial = self.solver.check() == z3.unsat
|
140
|
+
|
141
|
+
self.solver.pop()
|
142
|
+
return trivial
|
143
|
+
|
144
|
+
def _remove_control(self, gate, ctrlvar, trgtvar):
|
145
|
+
"""use z3 sat solver to determine if all control qubits are in 1 state,
|
146
|
+
and if so replace the Controlled - U by U.
|
147
|
+
Args:
|
148
|
+
gate (Gate): gate to inspect
|
149
|
+
ctrlvar (list(BoolRef)): z3 variables corresponding to latest state
|
150
|
+
of control qubits
|
151
|
+
trgtvar (list(BoolRef)): z3 variables corresponding to latest state
|
152
|
+
of target qubits
|
153
|
+
Returns:
|
154
|
+
Tuple(bool, DAGCircuit, List)::
|
155
|
+
* bool:if controlled gate can be replaced.
|
156
|
+
* DAGCircuit: with U applied to the target qubits.
|
157
|
+
* List: with indices of target qubits.
|
158
|
+
"""
|
159
|
+
remove = False
|
160
|
+
|
161
|
+
qarg = QuantumRegister(gate.num_qubits)
|
162
|
+
dag = DAGCircuit()
|
163
|
+
dag.add_qreg(qarg)
|
164
|
+
|
165
|
+
qb = list(range(len(ctrlvar), gate.num_qubits)) # last qubits as target.
|
166
|
+
|
167
|
+
if isinstance(gate, ControlledGate):
|
168
|
+
remove = self._check_removal(ctrlvar)
|
169
|
+
|
170
|
+
# try with other qubit as 'target'.
|
171
|
+
if isinstance(gate, (CZGate, CU1Gate, MCU1Gate)):
|
172
|
+
while not remove and qb[0] > 0:
|
173
|
+
qb[0] = qb[0] - 1
|
174
|
+
ctrl_vars = ctrlvar[: qb[0]] + ctrlvar[qb[0] + 1 :] + trgtvar
|
175
|
+
remove = self._check_removal(ctrl_vars)
|
176
|
+
|
177
|
+
if remove:
|
178
|
+
qubits = [qarg[qi] for qi in qb]
|
179
|
+
dag.apply_operation_back(gate.base_gate, qubits)
|
180
|
+
|
181
|
+
return remove, dag, qb
|
182
|
+
|
183
|
+
def _check_removal(self, ctrlvar):
|
184
|
+
import z3
|
185
|
+
|
186
|
+
ctrl_ones = z3.And(*ctrlvar)
|
187
|
+
|
188
|
+
self.solver.push()
|
189
|
+
self.solver.add(z3.Not(ctrl_ones))
|
190
|
+
remove = self.solver.check() == z3.unsat
|
191
|
+
self.solver.pop()
|
192
|
+
|
193
|
+
return remove
|
194
|
+
|
195
|
+
def _traverse_dag(self, dag):
|
196
|
+
"""traverse DAG in topological order
|
197
|
+
for each gate check: if any control is 0, or
|
198
|
+
if triviality conditions are satisfied
|
199
|
+
if yes remove gate from dag
|
200
|
+
apply postconditions of gate
|
201
|
+
Args:
|
202
|
+
dag (DAGCircuit): input DAG to optimize in place
|
203
|
+
"""
|
204
|
+
import z3
|
205
|
+
|
206
|
+
# Pre-generate all DAG nodes, since we later iterate over them, while
|
207
|
+
# potentially modifying and removing some of them.
|
208
|
+
nodes = list(dag.topological_op_nodes())
|
209
|
+
for node in nodes:
|
210
|
+
gate = node.op
|
211
|
+
_, ctrlvar, trgtqb, trgtvar = self._seperate_ctrl_trgt(node)
|
212
|
+
|
213
|
+
ctrl_ones = z3.And(*ctrlvar)
|
214
|
+
|
215
|
+
remove_ctrl, new_dag, _ = self._remove_control(gate, ctrlvar, trgtvar)
|
216
|
+
|
217
|
+
if remove_ctrl:
|
218
|
+
# We are replacing a node by a new node over a smaller number of qubits.
|
219
|
+
# This can be done using substitute_node_with_dag, which furthermore returns
|
220
|
+
# a mapping from old node ids to new nodes.
|
221
|
+
mapped_nodes = dag.substitute_node_with_dag(node, new_dag)
|
222
|
+
node = next(iter(mapped_nodes.values()))
|
223
|
+
gate = node.op
|
224
|
+
_, ctrlvar, trgtqb, trgtvar = self._seperate_ctrl_trgt(node)
|
225
|
+
|
226
|
+
ctrl_ones = z3.And(*ctrlvar)
|
227
|
+
|
228
|
+
trivial = self._test_gate(gate, ctrl_ones, trgtvar)
|
229
|
+
if trivial:
|
230
|
+
dag.remove_op_node(node)
|
231
|
+
elif self.size > 1:
|
232
|
+
for qbt in node.qargs:
|
233
|
+
self.gatecache[qbt].append(node)
|
234
|
+
self.varnum[qbt][node] = self.gatenum[qbt] - 1
|
235
|
+
for qbt in node.qargs:
|
236
|
+
if len(self.gatecache[qbt]) >= self.size:
|
237
|
+
self._multigate_opt(dag, qbt)
|
238
|
+
|
239
|
+
self._add_postconditions(gate, ctrl_ones, trgtqb, trgtvar)
|
240
|
+
|
241
|
+
def _remove_successive_identity(self, dag, qubit, from_idx=None):
|
242
|
+
"""remove gates that have the same set of target qubits, follow each
|
243
|
+
other immediately on these target qubits, and combine to the
|
244
|
+
identity (consider sequences of length 2 for now)
|
245
|
+
Args:
|
246
|
+
dag (DAGCircuit): the directed acyclic graph to run on.
|
247
|
+
qubit (Qubit): qubit cache to inspect
|
248
|
+
from_idx (int): only gates whose indexes in the cache are larger
|
249
|
+
than this value can be removed
|
250
|
+
"""
|
251
|
+
i = 0
|
252
|
+
while i < len(self.gatecache[qubit]) - 1:
|
253
|
+
append = True
|
254
|
+
node1 = self.gatecache[qubit][i]
|
255
|
+
node2 = self.gatecache[qubit][i + 1]
|
256
|
+
trgtqb1 = self._seperate_ctrl_trgt(node1)[2]
|
257
|
+
trgtqb2 = self._seperate_ctrl_trgt(node2)[2]
|
258
|
+
i += 1
|
259
|
+
|
260
|
+
if trgtqb1 != trgtqb2:
|
261
|
+
continue
|
262
|
+
try:
|
263
|
+
for qbt in trgtqb1:
|
264
|
+
idx = self.gatecache[qbt].index(node1)
|
265
|
+
if self.gatecache[qbt][idx + 1] is not node2:
|
266
|
+
append = False
|
267
|
+
except (IndexError, ValueError):
|
268
|
+
continue
|
269
|
+
|
270
|
+
seq = [node1, node2]
|
271
|
+
if append and self._is_identity(seq) and self._seq_as_one(seq):
|
272
|
+
i += 1
|
273
|
+
for node in seq:
|
274
|
+
dag.remove_op_node(node)
|
275
|
+
if from_idx is None or self.gatecache[qubit].index(node) > from_idx:
|
276
|
+
for qbt in node.qargs:
|
277
|
+
self.gatecache[qbt].remove(node)
|
278
|
+
|
279
|
+
def _is_identity(self, sequence):
|
280
|
+
"""determine whether the sequence of gates combines to the identity
|
281
|
+
(consider sequences of length 2 for now)
|
282
|
+
Args:
|
283
|
+
sequence (list(DAGOpNode)): gate sequence to inspect
|
284
|
+
Returns:
|
285
|
+
bool: if gate sequence combines to identity
|
286
|
+
"""
|
287
|
+
assert len(sequence) == 2
|
288
|
+
# some Instructions (e.g measurements) may not have an inverse.
|
289
|
+
try:
|
290
|
+
gate1, gate2 = sequence[0].op, sequence[1].op.inverse()
|
291
|
+
except CircuitError:
|
292
|
+
return False
|
293
|
+
par1, par2 = gate1.params, gate2.params
|
294
|
+
def1, def2 = gate1.definition, gate2.definition
|
295
|
+
|
296
|
+
if isinstance(gate1, ControlledGate):
|
297
|
+
gate1 = gate1.base_gate
|
298
|
+
gate1 = gate1.base_class
|
299
|
+
if isinstance(gate2, ControlledGate):
|
300
|
+
gate2 = gate2.base_gate
|
301
|
+
gate2 = gate2.base_class
|
302
|
+
|
303
|
+
# equality of gates can be determined via type and parameters, unless
|
304
|
+
# the gates have no specific type, in which case definition is used
|
305
|
+
# or they are unitary gates, in which case matrix equality is used
|
306
|
+
if gate1 is Gate and gate2 is Gate:
|
307
|
+
return def1 == def2 and def1 and def2
|
308
|
+
elif gate1 is UnitaryGate and gate2 is UnitaryGate:
|
309
|
+
return matrix_equal(par1[0], par2[0], ignore_phase=True)
|
310
|
+
|
311
|
+
return gate1 == gate2 and par1 == par2
|
312
|
+
|
313
|
+
def _seq_as_one(self, sequence):
|
314
|
+
"""use z3 solver to determine if the gates in the sequence are either
|
315
|
+
all executed or none of them are executed, based on control qubits
|
316
|
+
(consider sequences of length 2 for now)
|
317
|
+
Args:
|
318
|
+
sequence (list(DAGOpNode)): gate sequence to inspect
|
319
|
+
Returns:
|
320
|
+
bool: if gate sequence is only executed completely or not at all
|
321
|
+
"""
|
322
|
+
from z3 import Or, And, Not
|
323
|
+
import z3
|
324
|
+
|
325
|
+
assert len(sequence) == 2
|
326
|
+
ctrlvar1 = self._seperate_ctrl_trgt(sequence[0])[1]
|
327
|
+
ctrlvar2 = self._seperate_ctrl_trgt(sequence[1])[1]
|
328
|
+
|
329
|
+
self.solver.push()
|
330
|
+
self.solver.add(
|
331
|
+
Or(And(And(*ctrlvar1), Not(And(*ctrlvar2))), And(Not(And(*ctrlvar1)), And(*ctrlvar2)))
|
332
|
+
)
|
333
|
+
res = self.solver.check() == z3.unsat
|
334
|
+
self.solver.pop()
|
335
|
+
|
336
|
+
return res
|
337
|
+
|
338
|
+
def _multigate_opt(self, dag, qubit, max_idx=None, dnt_rec=None):
|
339
|
+
"""
|
340
|
+
Args:
|
341
|
+
dag (DAGCircuit): the directed acyclic graph to run on.
|
342
|
+
qubit (Qubit): qubit whose gate cache is to be optimized
|
343
|
+
max_idx (int): a value indicates a recursive call, optimize
|
344
|
+
and remove gates up to this point in the cache
|
345
|
+
dnt_rec (list(int)): don't recurse on these qubit caches (again)
|
346
|
+
"""
|
347
|
+
if not self.gatecache[qubit]:
|
348
|
+
return
|
349
|
+
|
350
|
+
# try to optimize this qubit's pipeline
|
351
|
+
self._remove_successive_identity(dag, qubit, max_idx)
|
352
|
+
if len(self.gatecache[qubit]) < self.size and max_idx is None:
|
353
|
+
# unless in a rec call, we are done if the cache isn't full
|
354
|
+
return
|
355
|
+
elif max_idx is None:
|
356
|
+
# need to remove at least one gate from cache, so remove oldest
|
357
|
+
max_idx = 0
|
358
|
+
dnt_rec = set()
|
359
|
+
dnt_rec.add(qubit)
|
360
|
+
gates_tbr = [self.gatecache[qubit][0]]
|
361
|
+
else:
|
362
|
+
# need to remove all gates up to max_idx (in reverse order)
|
363
|
+
gates_tbr = self.gatecache[qubit][max_idx::-1]
|
364
|
+
|
365
|
+
for node in gates_tbr:
|
366
|
+
# for rec call, only look at qubits that haven't been optimized yet
|
367
|
+
new_qb = [x for x in node.qargs if x not in dnt_rec]
|
368
|
+
dnt_rec.update(new_qb)
|
369
|
+
for qbt in new_qb:
|
370
|
+
idx = self.gatecache[qbt].index(node)
|
371
|
+
# recursive chain to optimize all gates in this qubit's cache
|
372
|
+
self._multigate_opt(dag, qbt, max_idx=idx, dnt_rec=dnt_rec)
|
373
|
+
# truncate gatecache for this qubit to after above gate
|
374
|
+
self.gatecache[qubit] = self.gatecache[qubit][max_idx + 1 :]
|
375
|
+
|
376
|
+
def _seperate_ctrl_trgt(self, node):
|
377
|
+
"""Get the target qubits and control qubits if available,
|
378
|
+
as well as their respective z3 variables.
|
379
|
+
"""
|
380
|
+
gate = node.op
|
381
|
+
if isinstance(gate, ControlledGate):
|
382
|
+
numctrl = gate.num_ctrl_qubits
|
383
|
+
else:
|
384
|
+
numctrl = 0
|
385
|
+
ctrlqb = node.qargs[:numctrl]
|
386
|
+
trgtqb = node.qargs[numctrl:]
|
387
|
+
try:
|
388
|
+
ctrlvar = [self.variables[qb][self.varnum[qb][node]] for qb in ctrlqb]
|
389
|
+
trgtvar = [self.variables[qb][self.varnum[qb][node]] for qb in trgtqb]
|
390
|
+
except KeyError:
|
391
|
+
ctrlvar = [self.variables[qb][-1] for qb in ctrlqb]
|
392
|
+
trgtvar = [self.variables[qb][-1] for qb in trgtqb]
|
393
|
+
return (ctrlqb, ctrlvar, trgtqb, trgtvar)
|
394
|
+
|
395
|
+
def _reset(self):
|
396
|
+
"""Reset HoareOptimize internal state,
|
397
|
+
so it can be run multiple times.
|
398
|
+
"""
|
399
|
+
import z3
|
400
|
+
|
401
|
+
self.solver = z3.Solver()
|
402
|
+
self.variables = {}
|
403
|
+
self.gatenum = {}
|
404
|
+
self.gatecache = {}
|
405
|
+
self.varnum = {}
|
406
|
+
|
407
|
+
def run(self, dag):
|
408
|
+
"""
|
409
|
+
Args:
|
410
|
+
dag (DAGCircuit): the directed acyclic graph to run on.
|
411
|
+
Returns:
|
412
|
+
DAGCircuit: Transformed DAG.
|
413
|
+
"""
|
414
|
+
self._reset()
|
415
|
+
self._initialize(dag)
|
416
|
+
self._traverse_dag(dag)
|
417
|
+
if self.size > 1:
|
418
|
+
for qbt in dag.qubits:
|
419
|
+
self._multigate_opt(dag, qbt)
|
420
|
+
return dag
|