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,1455 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2021.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
# pylint: disable=invalid-name
|
14
|
+
|
15
|
+
"""Binary IO for circuit objects."""
|
16
|
+
import itertools
|
17
|
+
from collections import defaultdict
|
18
|
+
import io
|
19
|
+
import json
|
20
|
+
import struct
|
21
|
+
import uuid
|
22
|
+
import warnings
|
23
|
+
|
24
|
+
import numpy as np
|
25
|
+
|
26
|
+
from qiskit import circuit as circuit_mod
|
27
|
+
from qiskit.circuit import library, controlflow, CircuitInstruction, ControlFlowOp, IfElseOp
|
28
|
+
from qiskit.circuit.classical import expr
|
29
|
+
from qiskit.circuit import ClassicalRegister, Clbit
|
30
|
+
from qiskit.circuit.gate import Gate
|
31
|
+
from qiskit.circuit.singleton import SingletonInstruction, SingletonGate
|
32
|
+
from qiskit.circuit.controlledgate import ControlledGate
|
33
|
+
from qiskit.circuit.annotated_operation import (
|
34
|
+
AnnotatedOperation,
|
35
|
+
Modifier,
|
36
|
+
InverseModifier,
|
37
|
+
ControlModifier,
|
38
|
+
PowerModifier,
|
39
|
+
)
|
40
|
+
from qiskit.circuit.instruction import Instruction
|
41
|
+
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
42
|
+
from qiskit.circuit import QuantumRegister, Qubit
|
43
|
+
from qiskit.qpy import common, formats, type_keys
|
44
|
+
from qiskit.qpy.binary_io import value, schedules
|
45
|
+
from qiskit.quantum_info.operators import SparsePauliOp, Clifford
|
46
|
+
from qiskit.synthesis import evolution as evo_synth
|
47
|
+
from qiskit.transpiler.layout import Layout, TranspileLayout
|
48
|
+
|
49
|
+
|
50
|
+
def _read_header_v12(file_obj, version, vectors, metadata_deserializer=None):
|
51
|
+
data = formats.CIRCUIT_HEADER_V12._make(
|
52
|
+
struct.unpack(
|
53
|
+
formats.CIRCUIT_HEADER_V12_PACK, file_obj.read(formats.CIRCUIT_HEADER_V12_SIZE)
|
54
|
+
)
|
55
|
+
)
|
56
|
+
name = file_obj.read(data.name_size).decode(common.ENCODE)
|
57
|
+
global_phase = value.loads_value(
|
58
|
+
data.global_phase_type,
|
59
|
+
file_obj.read(data.global_phase_size),
|
60
|
+
version=version,
|
61
|
+
vectors=vectors,
|
62
|
+
)
|
63
|
+
header = {
|
64
|
+
"global_phase": global_phase,
|
65
|
+
"num_qubits": data.num_qubits,
|
66
|
+
"num_clbits": data.num_clbits,
|
67
|
+
"num_registers": data.num_registers,
|
68
|
+
"num_instructions": data.num_instructions,
|
69
|
+
"num_vars": data.num_vars,
|
70
|
+
}
|
71
|
+
metadata_raw = file_obj.read(data.metadata_size)
|
72
|
+
metadata = json.loads(metadata_raw, cls=metadata_deserializer)
|
73
|
+
return header, name, metadata
|
74
|
+
|
75
|
+
|
76
|
+
def _read_header_v2(file_obj, version, vectors, metadata_deserializer=None):
|
77
|
+
data = formats.CIRCUIT_HEADER_V2._make(
|
78
|
+
struct.unpack(
|
79
|
+
formats.CIRCUIT_HEADER_V2_PACK,
|
80
|
+
file_obj.read(formats.CIRCUIT_HEADER_V2_SIZE),
|
81
|
+
)
|
82
|
+
)
|
83
|
+
|
84
|
+
name = file_obj.read(data.name_size).decode(common.ENCODE)
|
85
|
+
global_phase = value.loads_value(
|
86
|
+
data.global_phase_type,
|
87
|
+
file_obj.read(data.global_phase_size),
|
88
|
+
version=version,
|
89
|
+
vectors=vectors,
|
90
|
+
)
|
91
|
+
header = {
|
92
|
+
"global_phase": global_phase,
|
93
|
+
"num_qubits": data.num_qubits,
|
94
|
+
"num_clbits": data.num_clbits,
|
95
|
+
"num_registers": data.num_registers,
|
96
|
+
"num_instructions": data.num_instructions,
|
97
|
+
}
|
98
|
+
|
99
|
+
metadata_raw = file_obj.read(data.metadata_size)
|
100
|
+
metadata = json.loads(metadata_raw, cls=metadata_deserializer)
|
101
|
+
return header, name, metadata
|
102
|
+
|
103
|
+
|
104
|
+
def _read_header(file_obj, metadata_deserializer=None):
|
105
|
+
data = formats.CIRCUIT_HEADER._make(
|
106
|
+
struct.unpack(formats.CIRCUIT_HEADER_PACK, file_obj.read(formats.CIRCUIT_HEADER_SIZE))
|
107
|
+
)
|
108
|
+
name = file_obj.read(data.name_size).decode(common.ENCODE)
|
109
|
+
header = {
|
110
|
+
"global_phase": data.global_phase,
|
111
|
+
"num_qubits": data.num_qubits,
|
112
|
+
"num_clbits": data.num_clbits,
|
113
|
+
"num_registers": data.num_registers,
|
114
|
+
"num_instructions": data.num_instructions,
|
115
|
+
}
|
116
|
+
metadata_raw = file_obj.read(data.metadata_size)
|
117
|
+
metadata = json.loads(metadata_raw, cls=metadata_deserializer)
|
118
|
+
return header, name, metadata
|
119
|
+
|
120
|
+
|
121
|
+
def _read_registers_v4(file_obj, num_registers):
|
122
|
+
registers = {"q": {}, "c": {}}
|
123
|
+
for _reg in range(num_registers):
|
124
|
+
data = formats.REGISTER_V4._make(
|
125
|
+
struct.unpack(
|
126
|
+
formats.REGISTER_V4_PACK,
|
127
|
+
file_obj.read(formats.REGISTER_V4_SIZE),
|
128
|
+
)
|
129
|
+
)
|
130
|
+
name = file_obj.read(data.name_size).decode("utf8")
|
131
|
+
REGISTER_ARRAY_PACK = f"!{data.size}q"
|
132
|
+
bit_indices_raw = file_obj.read(struct.calcsize(REGISTER_ARRAY_PACK))
|
133
|
+
bit_indices = list(struct.unpack(REGISTER_ARRAY_PACK, bit_indices_raw))
|
134
|
+
if data.type.decode("utf8") == "q":
|
135
|
+
registers["q"][name] = (data.standalone, bit_indices, data.in_circuit)
|
136
|
+
else:
|
137
|
+
registers["c"][name] = (data.standalone, bit_indices, data.in_circuit)
|
138
|
+
return registers
|
139
|
+
|
140
|
+
|
141
|
+
def _read_registers(file_obj, num_registers):
|
142
|
+
registers = {"q": {}, "c": {}}
|
143
|
+
for _reg in range(num_registers):
|
144
|
+
data = formats.REGISTER._make(
|
145
|
+
struct.unpack(
|
146
|
+
formats.REGISTER_PACK,
|
147
|
+
file_obj.read(formats.REGISTER_SIZE),
|
148
|
+
)
|
149
|
+
)
|
150
|
+
name = file_obj.read(data.name_size).decode("utf8")
|
151
|
+
REGISTER_ARRAY_PACK = f"!{data.size}I"
|
152
|
+
bit_indices_raw = file_obj.read(struct.calcsize(REGISTER_ARRAY_PACK))
|
153
|
+
bit_indices = list(struct.unpack(REGISTER_ARRAY_PACK, bit_indices_raw))
|
154
|
+
if data.type.decode("utf8") == "q":
|
155
|
+
registers["q"][name] = (data.standalone, bit_indices, True)
|
156
|
+
else:
|
157
|
+
registers["c"][name] = (data.standalone, bit_indices, True)
|
158
|
+
return registers
|
159
|
+
|
160
|
+
|
161
|
+
def _loads_instruction_parameter(
|
162
|
+
type_key,
|
163
|
+
data_bytes,
|
164
|
+
version,
|
165
|
+
vectors,
|
166
|
+
registers,
|
167
|
+
circuit,
|
168
|
+
use_symengine,
|
169
|
+
standalone_vars,
|
170
|
+
):
|
171
|
+
if type_key == type_keys.Program.CIRCUIT:
|
172
|
+
param = common.data_from_binary(data_bytes, read_circuit, version=version)
|
173
|
+
elif type_key == type_keys.Value.MODIFIER:
|
174
|
+
param = common.data_from_binary(data_bytes, _read_modifier)
|
175
|
+
elif type_key == type_keys.Container.RANGE:
|
176
|
+
data = formats.RANGE._make(struct.unpack(formats.RANGE_PACK, data_bytes))
|
177
|
+
param = range(data.start, data.stop, data.step)
|
178
|
+
elif type_key == type_keys.Container.TUPLE:
|
179
|
+
param = tuple(
|
180
|
+
common.sequence_from_binary(
|
181
|
+
data_bytes,
|
182
|
+
_loads_instruction_parameter,
|
183
|
+
version=version,
|
184
|
+
vectors=vectors,
|
185
|
+
registers=registers,
|
186
|
+
circuit=circuit,
|
187
|
+
use_symengine=use_symengine,
|
188
|
+
standalone_vars=standalone_vars,
|
189
|
+
)
|
190
|
+
)
|
191
|
+
elif type_key == type_keys.Value.INTEGER:
|
192
|
+
# TODO This uses little endian. Should be fixed in the next QPY version.
|
193
|
+
param = struct.unpack("<q", data_bytes)[0]
|
194
|
+
elif type_key == type_keys.Value.FLOAT:
|
195
|
+
# TODO This uses little endian. Should be fixed in the next QPY version.
|
196
|
+
param = struct.unpack("<d", data_bytes)[0]
|
197
|
+
elif type_key == type_keys.Value.REGISTER:
|
198
|
+
param = _loads_register_param(data_bytes.decode(common.ENCODE), circuit, registers)
|
199
|
+
else:
|
200
|
+
clbits = circuit.clbits if circuit is not None else ()
|
201
|
+
param = value.loads_value(
|
202
|
+
type_key,
|
203
|
+
data_bytes,
|
204
|
+
version,
|
205
|
+
vectors,
|
206
|
+
clbits=clbits,
|
207
|
+
cregs=registers["c"],
|
208
|
+
use_symengine=use_symengine,
|
209
|
+
standalone_vars=standalone_vars,
|
210
|
+
)
|
211
|
+
|
212
|
+
return param
|
213
|
+
|
214
|
+
|
215
|
+
def _loads_register_param(data_bytes, circuit, registers):
|
216
|
+
# If register name prefixed with null character it's a clbit index for single bit condition.
|
217
|
+
if data_bytes[0] == "\x00":
|
218
|
+
conditional_bit = int(data_bytes[1:])
|
219
|
+
return circuit.clbits[conditional_bit]
|
220
|
+
return registers["c"][data_bytes]
|
221
|
+
|
222
|
+
|
223
|
+
def _read_instruction(
|
224
|
+
file_obj,
|
225
|
+
circuit,
|
226
|
+
registers,
|
227
|
+
custom_operations,
|
228
|
+
version,
|
229
|
+
vectors,
|
230
|
+
use_symengine,
|
231
|
+
standalone_vars,
|
232
|
+
):
|
233
|
+
if version < 5:
|
234
|
+
instruction = formats.CIRCUIT_INSTRUCTION._make(
|
235
|
+
struct.unpack(
|
236
|
+
formats.CIRCUIT_INSTRUCTION_PACK,
|
237
|
+
file_obj.read(formats.CIRCUIT_INSTRUCTION_SIZE),
|
238
|
+
)
|
239
|
+
)
|
240
|
+
else:
|
241
|
+
instruction = formats.CIRCUIT_INSTRUCTION_V2._make(
|
242
|
+
struct.unpack(
|
243
|
+
formats.CIRCUIT_INSTRUCTION_V2_PACK,
|
244
|
+
file_obj.read(formats.CIRCUIT_INSTRUCTION_V2_SIZE),
|
245
|
+
)
|
246
|
+
)
|
247
|
+
gate_name = file_obj.read(instruction.name_size).decode(common.ENCODE)
|
248
|
+
label = file_obj.read(instruction.label_size).decode(common.ENCODE)
|
249
|
+
condition_register = file_obj.read(instruction.condition_register_size).decode(common.ENCODE)
|
250
|
+
qargs = []
|
251
|
+
cargs = []
|
252
|
+
params = []
|
253
|
+
condition = None
|
254
|
+
if (version < 5 and instruction.has_condition) or (
|
255
|
+
version >= 5 and instruction.conditional_key == type_keys.Condition.TWO_TUPLE
|
256
|
+
):
|
257
|
+
condition = (
|
258
|
+
_loads_register_param(condition_register, circuit, registers),
|
259
|
+
instruction.condition_value,
|
260
|
+
)
|
261
|
+
elif version >= 5 and instruction.conditional_key == type_keys.Condition.EXPRESSION:
|
262
|
+
condition = value.read_value(
|
263
|
+
file_obj,
|
264
|
+
version,
|
265
|
+
vectors,
|
266
|
+
clbits=circuit.clbits,
|
267
|
+
cregs=registers["c"],
|
268
|
+
use_symengine=use_symengine,
|
269
|
+
standalone_vars=standalone_vars,
|
270
|
+
)
|
271
|
+
# Load Arguments
|
272
|
+
if circuit is not None:
|
273
|
+
for _qarg in range(instruction.num_qargs):
|
274
|
+
qarg = formats.CIRCUIT_INSTRUCTION_ARG._make(
|
275
|
+
struct.unpack(
|
276
|
+
formats.CIRCUIT_INSTRUCTION_ARG_PACK,
|
277
|
+
file_obj.read(formats.CIRCUIT_INSTRUCTION_ARG_SIZE),
|
278
|
+
)
|
279
|
+
)
|
280
|
+
if qarg.type.decode(common.ENCODE) == "c":
|
281
|
+
raise TypeError("Invalid input carg prior to all qargs")
|
282
|
+
qargs.append(circuit.qubits[qarg.size])
|
283
|
+
for _carg in range(instruction.num_cargs):
|
284
|
+
carg = formats.CIRCUIT_INSTRUCTION_ARG._make(
|
285
|
+
struct.unpack(
|
286
|
+
formats.CIRCUIT_INSTRUCTION_ARG_PACK,
|
287
|
+
file_obj.read(formats.CIRCUIT_INSTRUCTION_ARG_SIZE),
|
288
|
+
)
|
289
|
+
)
|
290
|
+
if carg.type.decode(common.ENCODE) == "q":
|
291
|
+
raise TypeError("Invalid input qarg after all qargs")
|
292
|
+
cargs.append(circuit.clbits[carg.size])
|
293
|
+
|
294
|
+
# Load Parameters
|
295
|
+
for _param in range(instruction.num_parameters):
|
296
|
+
type_key, data_bytes = common.read_generic_typed_data(file_obj)
|
297
|
+
param = _loads_instruction_parameter(
|
298
|
+
type_key,
|
299
|
+
data_bytes,
|
300
|
+
version,
|
301
|
+
vectors,
|
302
|
+
registers,
|
303
|
+
circuit,
|
304
|
+
use_symengine,
|
305
|
+
standalone_vars,
|
306
|
+
)
|
307
|
+
params.append(param)
|
308
|
+
|
309
|
+
# Load Gate object
|
310
|
+
if gate_name in {"Gate", "Instruction", "ControlledGate"}:
|
311
|
+
inst_obj = _parse_custom_operation(
|
312
|
+
custom_operations,
|
313
|
+
gate_name,
|
314
|
+
params,
|
315
|
+
version,
|
316
|
+
vectors,
|
317
|
+
registers,
|
318
|
+
use_symengine,
|
319
|
+
standalone_vars,
|
320
|
+
)
|
321
|
+
if condition is not None:
|
322
|
+
warnings.warn(
|
323
|
+
f"The .condition attribute on {gate_name} can not be "
|
324
|
+
"represented in this version of Qiskit. It will be "
|
325
|
+
"represented as an IfElseOp instead.",
|
326
|
+
UserWarning,
|
327
|
+
stacklevel=3,
|
328
|
+
)
|
329
|
+
|
330
|
+
body = QuantumCircuit(qargs, cargs)
|
331
|
+
body.append(inst_obj, qargs, cargs)
|
332
|
+
inst_obj = IfElseOp(condition, body)
|
333
|
+
if instruction.label_size > 0:
|
334
|
+
inst_obj.label = label
|
335
|
+
if circuit is None:
|
336
|
+
return inst_obj
|
337
|
+
circuit._append(inst_obj, qargs, cargs)
|
338
|
+
return None
|
339
|
+
elif gate_name in custom_operations:
|
340
|
+
inst_obj = _parse_custom_operation(
|
341
|
+
custom_operations,
|
342
|
+
gate_name,
|
343
|
+
params,
|
344
|
+
version,
|
345
|
+
vectors,
|
346
|
+
registers,
|
347
|
+
use_symengine,
|
348
|
+
standalone_vars,
|
349
|
+
)
|
350
|
+
inst_obj.condition = condition
|
351
|
+
if instruction.label_size > 0:
|
352
|
+
inst_obj.label = label
|
353
|
+
if circuit is None:
|
354
|
+
return inst_obj
|
355
|
+
circuit._append(inst_obj, qargs, cargs)
|
356
|
+
return None
|
357
|
+
elif hasattr(library, gate_name):
|
358
|
+
gate_class = getattr(library, gate_name)
|
359
|
+
elif hasattr(circuit_mod, gate_name):
|
360
|
+
gate_class = getattr(circuit_mod, gate_name)
|
361
|
+
elif hasattr(controlflow, gate_name):
|
362
|
+
gate_class = getattr(controlflow, gate_name)
|
363
|
+
elif gate_name == "Clifford":
|
364
|
+
gate_class = Clifford
|
365
|
+
else:
|
366
|
+
raise AttributeError(f"Invalid instruction type: {gate_name}")
|
367
|
+
|
368
|
+
if instruction.label_size <= 0:
|
369
|
+
label = None
|
370
|
+
if gate_name in ("IfElseOp", "WhileLoopOp"):
|
371
|
+
gate = gate_class(condition, *params, label=label)
|
372
|
+
elif gate_name == "BoxOp":
|
373
|
+
*params, duration, unit = params
|
374
|
+
gate = gate_class(*params, label=label, duration=duration, unit=unit)
|
375
|
+
elif version >= 5 and issubclass(gate_class, ControlledGate):
|
376
|
+
if gate_name in {
|
377
|
+
"MCPhaseGate",
|
378
|
+
"MCU1Gate",
|
379
|
+
"MCXGrayCode",
|
380
|
+
"MCXGate",
|
381
|
+
"MCXRecursive",
|
382
|
+
"MCXVChain",
|
383
|
+
}:
|
384
|
+
gate = gate_class(*params, instruction.num_ctrl_qubits, label=label)
|
385
|
+
else:
|
386
|
+
gate = gate_class(*params, label=label)
|
387
|
+
if (
|
388
|
+
gate.num_ctrl_qubits != instruction.num_ctrl_qubits
|
389
|
+
or gate.ctrl_state != instruction.ctrl_state
|
390
|
+
):
|
391
|
+
gate = gate.to_mutable()
|
392
|
+
gate.num_ctrl_qubits = instruction.num_ctrl_qubits
|
393
|
+
gate.ctrl_state = instruction.ctrl_state
|
394
|
+
if condition:
|
395
|
+
body = QuantumCircuit(qargs, cargs)
|
396
|
+
body.append(gate, qargs, cargs)
|
397
|
+
gate = IfElseOp(condition, body)
|
398
|
+
else:
|
399
|
+
if gate_name in {"Initialize", "StatePreparation"}:
|
400
|
+
if isinstance(params[0], str):
|
401
|
+
# the params are the labels of the initial state
|
402
|
+
gate = gate_class("".join(label for label in params))
|
403
|
+
elif instruction.num_parameters == 1:
|
404
|
+
# the params is the integer indicating which qubits to initialize
|
405
|
+
gate = gate_class(int(params[0].real), instruction.num_qargs)
|
406
|
+
else:
|
407
|
+
# the params represent a list of complex amplitudes
|
408
|
+
gate = gate_class(params)
|
409
|
+
elif gate_name in {
|
410
|
+
"UCRXGate",
|
411
|
+
"UCRYGate",
|
412
|
+
"UCRZGate",
|
413
|
+
"DiagonalGate",
|
414
|
+
}:
|
415
|
+
gate = gate_class(params)
|
416
|
+
elif gate_name == "QFTGate":
|
417
|
+
gate = gate_class(len(qargs), *params)
|
418
|
+
else:
|
419
|
+
if gate_name == "Barrier":
|
420
|
+
params = [len(qargs)]
|
421
|
+
elif gate_name in {"BreakLoopOp", "ContinueLoopOp"}:
|
422
|
+
params = [len(qargs), len(cargs)]
|
423
|
+
if label is not None:
|
424
|
+
if issubclass(gate_class, (SingletonInstruction, SingletonGate)):
|
425
|
+
gate = gate_class(*params, label=label)
|
426
|
+
else:
|
427
|
+
gate = gate_class(*params)
|
428
|
+
gate.label = label
|
429
|
+
else:
|
430
|
+
gate = gate_class(*params)
|
431
|
+
if condition:
|
432
|
+
if not isinstance(gate, ControlFlowOp):
|
433
|
+
warnings.warn(
|
434
|
+
f"The .condition attribute on {gate_name} can not be "
|
435
|
+
"represented in this version of Qiskit. It will be "
|
436
|
+
"represented as an IfElseOp instead.",
|
437
|
+
UserWarning,
|
438
|
+
stacklevel=3,
|
439
|
+
)
|
440
|
+
body = QuantumCircuit(qargs, cargs)
|
441
|
+
body.append(gate, qargs, cargs)
|
442
|
+
gate = IfElseOp(condition, body)
|
443
|
+
else:
|
444
|
+
gate.condition = condition
|
445
|
+
if circuit is None:
|
446
|
+
return gate
|
447
|
+
if not isinstance(gate, Instruction):
|
448
|
+
circuit.append(gate, qargs, cargs)
|
449
|
+
else:
|
450
|
+
circuit._append(CircuitInstruction(gate, qargs, cargs))
|
451
|
+
return None
|
452
|
+
|
453
|
+
|
454
|
+
def _parse_custom_operation(
|
455
|
+
custom_operations,
|
456
|
+
gate_name,
|
457
|
+
params,
|
458
|
+
version,
|
459
|
+
vectors,
|
460
|
+
registers,
|
461
|
+
use_symengine,
|
462
|
+
standalone_vars,
|
463
|
+
):
|
464
|
+
if version >= 5:
|
465
|
+
(
|
466
|
+
type_str,
|
467
|
+
num_qubits,
|
468
|
+
num_clbits,
|
469
|
+
definition,
|
470
|
+
num_ctrl_qubits,
|
471
|
+
ctrl_state,
|
472
|
+
base_gate_raw,
|
473
|
+
) = custom_operations[gate_name]
|
474
|
+
else:
|
475
|
+
type_str, num_qubits, num_clbits, definition = custom_operations[gate_name]
|
476
|
+
base_gate_raw = ctrl_state = num_ctrl_qubits = None
|
477
|
+
# Strip the trailing "_{uuid}" from the gate name if the version >=11
|
478
|
+
if version >= 11:
|
479
|
+
gate_name = "_".join(gate_name.split("_")[:-1])
|
480
|
+
type_key = type_keys.CircuitInstruction(type_str)
|
481
|
+
|
482
|
+
if type_key == type_keys.CircuitInstruction.INSTRUCTION:
|
483
|
+
inst_obj = Instruction(gate_name, num_qubits, num_clbits, params)
|
484
|
+
if definition is not None:
|
485
|
+
inst_obj.definition = definition
|
486
|
+
return inst_obj
|
487
|
+
|
488
|
+
if type_key == type_keys.CircuitInstruction.GATE:
|
489
|
+
inst_obj = Gate(gate_name, num_qubits, params)
|
490
|
+
inst_obj.definition = definition
|
491
|
+
return inst_obj
|
492
|
+
|
493
|
+
if version >= 5 and type_key == type_keys.CircuitInstruction.CONTROLLED_GATE:
|
494
|
+
with io.BytesIO(base_gate_raw) as base_gate_obj:
|
495
|
+
base_gate = _read_instruction(
|
496
|
+
base_gate_obj,
|
497
|
+
None,
|
498
|
+
registers,
|
499
|
+
custom_operations,
|
500
|
+
version,
|
501
|
+
vectors,
|
502
|
+
use_symengine,
|
503
|
+
standalone_vars,
|
504
|
+
)
|
505
|
+
if ctrl_state < 2**num_ctrl_qubits - 1:
|
506
|
+
# If open controls, we need to discard the control suffix when setting the name.
|
507
|
+
gate_name = gate_name.rsplit("_", 1)[0]
|
508
|
+
inst_obj = ControlledGate(
|
509
|
+
gate_name,
|
510
|
+
num_qubits,
|
511
|
+
params,
|
512
|
+
num_ctrl_qubits=num_ctrl_qubits,
|
513
|
+
ctrl_state=ctrl_state,
|
514
|
+
base_gate=base_gate,
|
515
|
+
)
|
516
|
+
inst_obj.definition = definition
|
517
|
+
return inst_obj
|
518
|
+
|
519
|
+
if version >= 11 and type_key == type_keys.CircuitInstruction.ANNOTATED_OPERATION:
|
520
|
+
with io.BytesIO(base_gate_raw) as base_gate_obj:
|
521
|
+
base_gate = _read_instruction(
|
522
|
+
base_gate_obj,
|
523
|
+
None,
|
524
|
+
registers,
|
525
|
+
custom_operations,
|
526
|
+
version,
|
527
|
+
vectors,
|
528
|
+
use_symengine,
|
529
|
+
standalone_vars,
|
530
|
+
)
|
531
|
+
inst_obj = AnnotatedOperation(base_op=base_gate, modifiers=params)
|
532
|
+
return inst_obj
|
533
|
+
|
534
|
+
if type_key == type_keys.CircuitInstruction.PAULI_EVOL_GATE:
|
535
|
+
return definition
|
536
|
+
|
537
|
+
raise ValueError(f"Invalid custom instruction type '{type_str}'")
|
538
|
+
|
539
|
+
|
540
|
+
def _read_pauli_evolution_gate(file_obj, version, vectors):
|
541
|
+
pauli_evolution_def = formats.PAULI_EVOLUTION_DEF._make(
|
542
|
+
struct.unpack(
|
543
|
+
formats.PAULI_EVOLUTION_DEF_PACK, file_obj.read(formats.PAULI_EVOLUTION_DEF_SIZE)
|
544
|
+
)
|
545
|
+
)
|
546
|
+
if pauli_evolution_def.operator_size != 1 and pauli_evolution_def.standalone_op:
|
547
|
+
raise ValueError(
|
548
|
+
"Can't have a standalone operator with {pauli_evolution_raw[0]} operators in the payload"
|
549
|
+
)
|
550
|
+
|
551
|
+
operator_list = []
|
552
|
+
for _ in range(pauli_evolution_def.operator_size):
|
553
|
+
op_elem = formats.SPARSE_PAULI_OP_LIST_ELEM._make(
|
554
|
+
struct.unpack(
|
555
|
+
formats.SPARSE_PAULI_OP_LIST_ELEM_PACK,
|
556
|
+
file_obj.read(formats.SPARSE_PAULI_OP_LIST_ELEM_SIZE),
|
557
|
+
)
|
558
|
+
)
|
559
|
+
op_raw_data = common.data_from_binary(file_obj.read(op_elem.size), np.load)
|
560
|
+
operator_list.append(SparsePauliOp.from_list(op_raw_data))
|
561
|
+
|
562
|
+
if pauli_evolution_def.standalone_op:
|
563
|
+
pauli_op = operator_list[0]
|
564
|
+
else:
|
565
|
+
pauli_op = operator_list
|
566
|
+
|
567
|
+
time = value.loads_value(
|
568
|
+
pauli_evolution_def.time_type,
|
569
|
+
file_obj.read(pauli_evolution_def.time_size),
|
570
|
+
version=version,
|
571
|
+
vectors=vectors,
|
572
|
+
)
|
573
|
+
synth_data = json.loads(file_obj.read(pauli_evolution_def.synth_method_size))
|
574
|
+
synthesis = getattr(evo_synth, synth_data["class"])(**synth_data["settings"])
|
575
|
+
return_gate = library.PauliEvolutionGate(pauli_op, time=time, synthesis=synthesis)
|
576
|
+
return return_gate
|
577
|
+
|
578
|
+
|
579
|
+
def _read_modifier(file_obj):
|
580
|
+
modifier = formats.MODIFIER_DEF._make(
|
581
|
+
struct.unpack(
|
582
|
+
formats.MODIFIER_DEF_PACK,
|
583
|
+
file_obj.read(formats.MODIFIER_DEF_SIZE),
|
584
|
+
)
|
585
|
+
)
|
586
|
+
if modifier.type == b"i":
|
587
|
+
return InverseModifier()
|
588
|
+
elif modifier.type == b"c":
|
589
|
+
return ControlModifier(
|
590
|
+
num_ctrl_qubits=modifier.num_ctrl_qubits, ctrl_state=modifier.ctrl_state
|
591
|
+
)
|
592
|
+
elif modifier.type == b"p":
|
593
|
+
return PowerModifier(power=modifier.power)
|
594
|
+
else:
|
595
|
+
raise TypeError("Unsupported modifier.")
|
596
|
+
|
597
|
+
|
598
|
+
def _read_custom_operations(file_obj, version, vectors):
|
599
|
+
custom_operations = {}
|
600
|
+
custom_definition_header = formats.CUSTOM_CIRCUIT_DEF_HEADER._make(
|
601
|
+
struct.unpack(
|
602
|
+
formats.CUSTOM_CIRCUIT_DEF_HEADER_PACK,
|
603
|
+
file_obj.read(formats.CUSTOM_CIRCUIT_DEF_HEADER_SIZE),
|
604
|
+
)
|
605
|
+
)
|
606
|
+
if custom_definition_header.size > 0:
|
607
|
+
for _ in range(custom_definition_header.size):
|
608
|
+
if version < 5:
|
609
|
+
data = formats.CUSTOM_CIRCUIT_INST_DEF._make(
|
610
|
+
struct.unpack(
|
611
|
+
formats.CUSTOM_CIRCUIT_INST_DEF_PACK,
|
612
|
+
file_obj.read(formats.CUSTOM_CIRCUIT_INST_DEF_SIZE),
|
613
|
+
)
|
614
|
+
)
|
615
|
+
else:
|
616
|
+
data = formats.CUSTOM_CIRCUIT_INST_DEF_V2._make(
|
617
|
+
struct.unpack(
|
618
|
+
formats.CUSTOM_CIRCUIT_INST_DEF_V2_PACK,
|
619
|
+
file_obj.read(formats.CUSTOM_CIRCUIT_INST_DEF_V2_SIZE),
|
620
|
+
)
|
621
|
+
)
|
622
|
+
|
623
|
+
name = file_obj.read(data.gate_name_size).decode(common.ENCODE)
|
624
|
+
type_str = data.type
|
625
|
+
definition_circuit = None
|
626
|
+
if data.custom_definition:
|
627
|
+
def_binary = file_obj.read(data.size)
|
628
|
+
if version < 3 or not name.startswith(r"###PauliEvolutionGate_"):
|
629
|
+
definition_circuit = common.data_from_binary(
|
630
|
+
def_binary, read_circuit, version=version
|
631
|
+
)
|
632
|
+
elif name.startswith(r"###PauliEvolutionGate_"):
|
633
|
+
definition_circuit = common.data_from_binary(
|
634
|
+
def_binary, _read_pauli_evolution_gate, version=version, vectors=vectors
|
635
|
+
)
|
636
|
+
if version < 5:
|
637
|
+
data_payload = (type_str, data.num_qubits, data.num_clbits, definition_circuit)
|
638
|
+
else:
|
639
|
+
base_gate = file_obj.read(data.base_gate_size)
|
640
|
+
data_payload = (
|
641
|
+
type_str,
|
642
|
+
data.num_qubits,
|
643
|
+
data.num_clbits,
|
644
|
+
definition_circuit,
|
645
|
+
data.num_ctrl_qubits,
|
646
|
+
data.ctrl_state,
|
647
|
+
base_gate,
|
648
|
+
)
|
649
|
+
custom_operations[name] = data_payload
|
650
|
+
return custom_operations
|
651
|
+
|
652
|
+
|
653
|
+
def _read_calibrations(file_obj, version, vectors, metadata_deserializer):
|
654
|
+
"""Consume calibrations data, make the file handle point to the next section"""
|
655
|
+
header = formats.CALIBRATION._make(
|
656
|
+
struct.unpack(formats.CALIBRATION_PACK, file_obj.read(formats.CALIBRATION_SIZE))
|
657
|
+
)
|
658
|
+
for _ in range(header.num_cals):
|
659
|
+
defheader = formats.CALIBRATION_DEF._make(
|
660
|
+
struct.unpack(formats.CALIBRATION_DEF_PACK, file_obj.read(formats.CALIBRATION_DEF_SIZE))
|
661
|
+
)
|
662
|
+
name = file_obj.read(defheader.name_size).decode(common.ENCODE)
|
663
|
+
if name:
|
664
|
+
warnings.warn(
|
665
|
+
category=UserWarning,
|
666
|
+
message="Support for loading pulse gates has been removed in Qiskit 2.0. "
|
667
|
+
f"If `{name}` is in the circuit it will be left as an opaque instruction.",
|
668
|
+
)
|
669
|
+
|
670
|
+
for _ in range(defheader.num_qubits): # read qubits info
|
671
|
+
file_obj.read(struct.calcsize("!q"))
|
672
|
+
|
673
|
+
for _ in range(defheader.num_params): # read params info
|
674
|
+
value.read_value(file_obj, version, vectors)
|
675
|
+
|
676
|
+
schedules.read_schedule_block(file_obj, version, metadata_deserializer)
|
677
|
+
|
678
|
+
|
679
|
+
def _dumps_register(register, index_map):
|
680
|
+
if isinstance(register, ClassicalRegister):
|
681
|
+
return register.name.encode(common.ENCODE)
|
682
|
+
# Clbit.
|
683
|
+
return b"\x00" + str(index_map["c"][register]).encode(common.ENCODE)
|
684
|
+
|
685
|
+
|
686
|
+
def _dumps_instruction_parameter(
|
687
|
+
param, index_map, use_symengine, *, version, standalone_var_indices
|
688
|
+
):
|
689
|
+
if isinstance(param, QuantumCircuit):
|
690
|
+
type_key = type_keys.Program.CIRCUIT
|
691
|
+
data_bytes = common.data_to_binary(param, write_circuit, version=version)
|
692
|
+
elif isinstance(param, Modifier):
|
693
|
+
type_key = type_keys.Value.MODIFIER
|
694
|
+
data_bytes = common.data_to_binary(param, _write_modifier)
|
695
|
+
elif isinstance(param, range):
|
696
|
+
type_key = type_keys.Container.RANGE
|
697
|
+
data_bytes = struct.pack(formats.RANGE_PACK, param.start, param.stop, param.step)
|
698
|
+
elif isinstance(param, tuple):
|
699
|
+
type_key = type_keys.Container.TUPLE
|
700
|
+
data_bytes = common.sequence_to_binary(
|
701
|
+
param,
|
702
|
+
_dumps_instruction_parameter,
|
703
|
+
index_map=index_map,
|
704
|
+
use_symengine=use_symengine,
|
705
|
+
version=version,
|
706
|
+
standalone_var_indices=standalone_var_indices,
|
707
|
+
)
|
708
|
+
elif isinstance(param, int):
|
709
|
+
# TODO This uses little endian. This should be fixed in next QPY version.
|
710
|
+
type_key = type_keys.Value.INTEGER
|
711
|
+
data_bytes = struct.pack("<q", param)
|
712
|
+
elif isinstance(param, float):
|
713
|
+
# TODO This uses little endian. This should be fixed in next QPY version.
|
714
|
+
type_key = type_keys.Value.FLOAT
|
715
|
+
data_bytes = struct.pack("<d", param)
|
716
|
+
elif isinstance(param, (Clbit, ClassicalRegister)):
|
717
|
+
type_key = type_keys.Value.REGISTER
|
718
|
+
data_bytes = _dumps_register(param, index_map)
|
719
|
+
else:
|
720
|
+
type_key, data_bytes = value.dumps_value(
|
721
|
+
param,
|
722
|
+
index_map=index_map,
|
723
|
+
use_symengine=use_symengine,
|
724
|
+
standalone_var_indices=standalone_var_indices,
|
725
|
+
version=version,
|
726
|
+
)
|
727
|
+
|
728
|
+
return type_key, data_bytes
|
729
|
+
|
730
|
+
|
731
|
+
# pylint: disable=too-many-boolean-expressions
|
732
|
+
def _write_instruction(
|
733
|
+
file_obj,
|
734
|
+
instruction,
|
735
|
+
custom_operations,
|
736
|
+
index_map,
|
737
|
+
use_symengine,
|
738
|
+
version,
|
739
|
+
standalone_var_indices=None,
|
740
|
+
):
|
741
|
+
if isinstance(instruction.operation, Instruction):
|
742
|
+
gate_class_name = instruction.operation.base_class.__name__
|
743
|
+
else:
|
744
|
+
gate_class_name = instruction.operation.__class__.__name__
|
745
|
+
|
746
|
+
custom_operations_list = []
|
747
|
+
if (
|
748
|
+
(
|
749
|
+
not hasattr(library, gate_class_name)
|
750
|
+
and not hasattr(circuit_mod, gate_class_name)
|
751
|
+
and not hasattr(controlflow, gate_class_name)
|
752
|
+
and gate_class_name != "Clifford"
|
753
|
+
)
|
754
|
+
or gate_class_name == "Gate"
|
755
|
+
or gate_class_name == "Instruction"
|
756
|
+
or isinstance(instruction.operation, library.BlueprintCircuit)
|
757
|
+
):
|
758
|
+
gate_class_name = instruction.operation.name
|
759
|
+
# Assign a uuid to each instance of a custom operation
|
760
|
+
if instruction.operation.name not in {"ucrx_dg", "ucry_dg", "ucrz_dg"}:
|
761
|
+
gate_class_name = f"{gate_class_name}_{uuid.uuid4().hex}"
|
762
|
+
else:
|
763
|
+
# ucr*_dg gates can have different numbers of parameters,
|
764
|
+
# the uuid is appended to avoid storing a single definition
|
765
|
+
# in circuits with multiple ucr*_dg gates. For legacy reasons
|
766
|
+
# the uuid is stored in a different format as this was done
|
767
|
+
# prior to QPY 11.
|
768
|
+
gate_class_name = f"{gate_class_name}_{uuid.uuid4()}"
|
769
|
+
|
770
|
+
custom_operations[gate_class_name] = instruction.operation
|
771
|
+
custom_operations_list.append(gate_class_name)
|
772
|
+
|
773
|
+
elif gate_class_name in {"ControlledGate", "AnnotatedOperation"}:
|
774
|
+
# controlled or annotated gates can have the same name but different parameter
|
775
|
+
# values, the uuid is appended to avoid storing a single definition
|
776
|
+
# in circuits with multiple controlled gates.
|
777
|
+
gate_class_name = instruction.operation.name + "_" + str(uuid.uuid4())
|
778
|
+
custom_operations[gate_class_name] = instruction.operation
|
779
|
+
custom_operations_list.append(gate_class_name)
|
780
|
+
|
781
|
+
elif isinstance(instruction.operation, library.PauliEvolutionGate):
|
782
|
+
gate_class_name = r"###PauliEvolutionGate_" + str(uuid.uuid4())
|
783
|
+
custom_operations[gate_class_name] = instruction.operation
|
784
|
+
custom_operations_list.append(gate_class_name)
|
785
|
+
|
786
|
+
elif isinstance(instruction.operation, library.MCMTGate):
|
787
|
+
gate_class_name = instruction.operation.name + "_" + str(uuid.uuid4())
|
788
|
+
custom_operations[gate_class_name] = instruction.operation
|
789
|
+
custom_operations_list.append(gate_class_name)
|
790
|
+
|
791
|
+
condition_type = type_keys.Condition.NONE
|
792
|
+
condition_register = b""
|
793
|
+
condition_value = 0
|
794
|
+
if (op_condition := getattr(instruction.operation, "_condition", None)) is not None:
|
795
|
+
if isinstance(op_condition, expr.Expr):
|
796
|
+
condition_type = type_keys.Condition.EXPRESSION
|
797
|
+
else:
|
798
|
+
condition_type = type_keys.Condition.TWO_TUPLE
|
799
|
+
condition_register = _dumps_register(instruction.operation._condition[0], index_map)
|
800
|
+
condition_value = int(instruction.operation._condition[1])
|
801
|
+
|
802
|
+
gate_class_name = gate_class_name.encode(common.ENCODE)
|
803
|
+
label = getattr(instruction.operation, "label", None)
|
804
|
+
if label:
|
805
|
+
label_raw = label.encode(common.ENCODE)
|
806
|
+
else:
|
807
|
+
label_raw = b""
|
808
|
+
|
809
|
+
# The instruction params we store are about being able to reconstruct the objects; they don't
|
810
|
+
# necessarily need to match one-to-one to the `params` field.
|
811
|
+
if isinstance(instruction.operation, controlflow.SwitchCaseOp):
|
812
|
+
instruction_params = [
|
813
|
+
instruction.operation.target,
|
814
|
+
tuple(instruction.operation.cases_specifier()),
|
815
|
+
]
|
816
|
+
elif isinstance(instruction.operation, controlflow.BoxOp):
|
817
|
+
instruction_params = [
|
818
|
+
instruction.operation.blocks[0],
|
819
|
+
instruction.operation.duration,
|
820
|
+
instruction.operation.unit,
|
821
|
+
]
|
822
|
+
elif isinstance(instruction.operation, Clifford):
|
823
|
+
instruction_params = [instruction.operation.tableau]
|
824
|
+
elif isinstance(instruction.operation, AnnotatedOperation):
|
825
|
+
instruction_params = instruction.operation.modifiers
|
826
|
+
else:
|
827
|
+
instruction_params = getattr(instruction.operation, "params", [])
|
828
|
+
|
829
|
+
num_ctrl_qubits = getattr(instruction.operation, "num_ctrl_qubits", 0)
|
830
|
+
ctrl_state = getattr(instruction.operation, "ctrl_state", 0)
|
831
|
+
instruction_raw = struct.pack(
|
832
|
+
formats.CIRCUIT_INSTRUCTION_V2_PACK,
|
833
|
+
len(gate_class_name),
|
834
|
+
len(label_raw),
|
835
|
+
len(instruction_params),
|
836
|
+
instruction.operation.num_qubits,
|
837
|
+
instruction.operation.num_clbits,
|
838
|
+
condition_type.value,
|
839
|
+
len(condition_register),
|
840
|
+
condition_value,
|
841
|
+
num_ctrl_qubits,
|
842
|
+
ctrl_state,
|
843
|
+
)
|
844
|
+
file_obj.write(instruction_raw)
|
845
|
+
file_obj.write(gate_class_name)
|
846
|
+
file_obj.write(label_raw)
|
847
|
+
if condition_type is type_keys.Condition.EXPRESSION:
|
848
|
+
value.write_value(
|
849
|
+
file_obj,
|
850
|
+
op_condition,
|
851
|
+
version=version,
|
852
|
+
index_map=index_map,
|
853
|
+
standalone_var_indices=standalone_var_indices,
|
854
|
+
)
|
855
|
+
else:
|
856
|
+
file_obj.write(condition_register)
|
857
|
+
# Encode instruction args
|
858
|
+
for qbit in instruction.qubits:
|
859
|
+
instruction_arg_raw = struct.pack(
|
860
|
+
formats.CIRCUIT_INSTRUCTION_ARG_PACK, b"q", index_map["q"][qbit]
|
861
|
+
)
|
862
|
+
file_obj.write(instruction_arg_raw)
|
863
|
+
for clbit in instruction.clbits:
|
864
|
+
instruction_arg_raw = struct.pack(
|
865
|
+
formats.CIRCUIT_INSTRUCTION_ARG_PACK, b"c", index_map["c"][clbit]
|
866
|
+
)
|
867
|
+
file_obj.write(instruction_arg_raw)
|
868
|
+
# Encode instruction params
|
869
|
+
for param in instruction_params:
|
870
|
+
type_key, data_bytes = _dumps_instruction_parameter(
|
871
|
+
param,
|
872
|
+
index_map,
|
873
|
+
use_symengine,
|
874
|
+
version=version,
|
875
|
+
standalone_var_indices=standalone_var_indices,
|
876
|
+
)
|
877
|
+
common.write_generic_typed_data(file_obj, type_key, data_bytes)
|
878
|
+
return custom_operations_list
|
879
|
+
|
880
|
+
|
881
|
+
def _write_pauli_evolution_gate(file_obj, evolution_gate, version):
|
882
|
+
operator_list = evolution_gate.operator
|
883
|
+
standalone = False
|
884
|
+
if not isinstance(operator_list, list):
|
885
|
+
operator_list = [operator_list]
|
886
|
+
standalone = True
|
887
|
+
num_operators = len(operator_list)
|
888
|
+
|
889
|
+
def _write_elem(buffer, op):
|
890
|
+
elem_data = common.data_to_binary(op.to_list(array=True), np.save)
|
891
|
+
elem_metadata = struct.pack(formats.SPARSE_PAULI_OP_LIST_ELEM_PACK, len(elem_data))
|
892
|
+
buffer.write(elem_metadata)
|
893
|
+
buffer.write(elem_data)
|
894
|
+
|
895
|
+
pauli_data_buf = io.BytesIO()
|
896
|
+
for operator in operator_list:
|
897
|
+
data = common.data_to_binary(operator, _write_elem)
|
898
|
+
pauli_data_buf.write(data)
|
899
|
+
|
900
|
+
time_type, time_data = value.dumps_value(evolution_gate.time, version=version)
|
901
|
+
time_size = len(time_data)
|
902
|
+
synth_class = str(type(evolution_gate.synthesis).__name__)
|
903
|
+
settings_dict = evolution_gate.synthesis.settings
|
904
|
+
synth_data = json.dumps({"class": synth_class, "settings": settings_dict}).encode(common.ENCODE)
|
905
|
+
synth_size = len(synth_data)
|
906
|
+
pauli_evolution_raw = struct.pack(
|
907
|
+
formats.PAULI_EVOLUTION_DEF_PACK,
|
908
|
+
num_operators,
|
909
|
+
standalone,
|
910
|
+
time_type,
|
911
|
+
time_size,
|
912
|
+
synth_size,
|
913
|
+
)
|
914
|
+
file_obj.write(pauli_evolution_raw)
|
915
|
+
file_obj.write(pauli_data_buf.getvalue())
|
916
|
+
pauli_data_buf.close()
|
917
|
+
file_obj.write(time_data)
|
918
|
+
file_obj.write(synth_data)
|
919
|
+
|
920
|
+
|
921
|
+
def _write_modifier(file_obj, modifier):
|
922
|
+
if isinstance(modifier, InverseModifier):
|
923
|
+
type_key = b"i"
|
924
|
+
num_ctrl_qubits = 0
|
925
|
+
ctrl_state = 0
|
926
|
+
power = 0.0
|
927
|
+
elif isinstance(modifier, ControlModifier):
|
928
|
+
type_key = b"c"
|
929
|
+
num_ctrl_qubits = modifier.num_ctrl_qubits
|
930
|
+
ctrl_state = modifier.ctrl_state
|
931
|
+
power = 0.0
|
932
|
+
elif isinstance(modifier, PowerModifier):
|
933
|
+
type_key = b"p"
|
934
|
+
num_ctrl_qubits = 0
|
935
|
+
ctrl_state = 0
|
936
|
+
power = modifier.power
|
937
|
+
else:
|
938
|
+
raise TypeError("Unsupported modifier.")
|
939
|
+
|
940
|
+
modifier_data = struct.pack(
|
941
|
+
formats.MODIFIER_DEF_PACK, type_key, num_ctrl_qubits, ctrl_state, power
|
942
|
+
)
|
943
|
+
file_obj.write(modifier_data)
|
944
|
+
|
945
|
+
|
946
|
+
def _write_custom_operation(
|
947
|
+
file_obj, name, operation, custom_operations, use_symengine, version, *, standalone_var_indices
|
948
|
+
):
|
949
|
+
type_key = type_keys.CircuitInstruction.assign(operation)
|
950
|
+
has_definition = False
|
951
|
+
size = 0
|
952
|
+
data = None
|
953
|
+
num_qubits = operation.num_qubits
|
954
|
+
num_clbits = operation.num_clbits
|
955
|
+
ctrl_state = 0
|
956
|
+
num_ctrl_qubits = 0
|
957
|
+
base_gate = None
|
958
|
+
new_custom_instruction = []
|
959
|
+
|
960
|
+
if type_key == type_keys.CircuitInstruction.PAULI_EVOL_GATE:
|
961
|
+
has_definition = True
|
962
|
+
data = common.data_to_binary(operation, _write_pauli_evolution_gate, version=version)
|
963
|
+
size = len(data)
|
964
|
+
elif type_key == type_keys.CircuitInstruction.CONTROLLED_GATE:
|
965
|
+
# For ControlledGate, we have to access and store the private `_definition` rather than the
|
966
|
+
# public one, because the public one is mutated to include additional logic if the control
|
967
|
+
# state is open, and the definition setter (during a subsequent read) uses the "fully
|
968
|
+
# excited" control definition only.
|
969
|
+
has_definition = True
|
970
|
+
# Build internal definition to support overloaded subclasses by
|
971
|
+
# calling definition getter on object
|
972
|
+
operation.definition # pylint: disable=pointless-statement
|
973
|
+
data = common.data_to_binary(operation._definition, write_circuit, version=version)
|
974
|
+
size = len(data)
|
975
|
+
num_ctrl_qubits = operation.num_ctrl_qubits
|
976
|
+
ctrl_state = operation.ctrl_state
|
977
|
+
base_gate = operation.base_gate
|
978
|
+
elif type_key == type_keys.CircuitInstruction.ANNOTATED_OPERATION:
|
979
|
+
has_definition = False
|
980
|
+
base_gate = operation.base_op
|
981
|
+
elif operation.definition is not None:
|
982
|
+
has_definition = True
|
983
|
+
data = common.data_to_binary(operation.definition, write_circuit, version=version)
|
984
|
+
size = len(data)
|
985
|
+
if base_gate is None:
|
986
|
+
base_gate_raw = b""
|
987
|
+
else:
|
988
|
+
with io.BytesIO() as base_gate_buffer:
|
989
|
+
new_custom_instruction = _write_instruction(
|
990
|
+
base_gate_buffer,
|
991
|
+
CircuitInstruction(base_gate, (), ()),
|
992
|
+
custom_operations,
|
993
|
+
{},
|
994
|
+
use_symengine,
|
995
|
+
version,
|
996
|
+
standalone_var_indices=standalone_var_indices,
|
997
|
+
)
|
998
|
+
base_gate_raw = base_gate_buffer.getvalue()
|
999
|
+
name_raw = name.encode(common.ENCODE)
|
1000
|
+
custom_operation_raw = struct.pack(
|
1001
|
+
formats.CUSTOM_CIRCUIT_INST_DEF_V2_PACK,
|
1002
|
+
len(name_raw),
|
1003
|
+
type_key,
|
1004
|
+
num_qubits,
|
1005
|
+
num_clbits,
|
1006
|
+
has_definition,
|
1007
|
+
size,
|
1008
|
+
num_ctrl_qubits,
|
1009
|
+
ctrl_state,
|
1010
|
+
len(base_gate_raw),
|
1011
|
+
)
|
1012
|
+
file_obj.write(custom_operation_raw)
|
1013
|
+
file_obj.write(name_raw)
|
1014
|
+
if data:
|
1015
|
+
file_obj.write(data)
|
1016
|
+
file_obj.write(base_gate_raw)
|
1017
|
+
return new_custom_instruction
|
1018
|
+
|
1019
|
+
|
1020
|
+
def _write_registers(file_obj, in_circ_regs, full_bits):
|
1021
|
+
bitmap = {bit: index for index, bit in enumerate(full_bits)}
|
1022
|
+
|
1023
|
+
out_circ_regs = set()
|
1024
|
+
for bit in full_bits:
|
1025
|
+
if bit._register is not None and bit._register not in in_circ_regs:
|
1026
|
+
out_circ_regs.add(bit._register)
|
1027
|
+
|
1028
|
+
for regs, is_in_circuit in [(in_circ_regs, True), (out_circ_regs, False)]:
|
1029
|
+
for reg in regs:
|
1030
|
+
standalone = all(
|
1031
|
+
bit._register == reg and bit._index == index for index, bit in enumerate(reg)
|
1032
|
+
)
|
1033
|
+
reg_name = reg.name.encode(common.ENCODE)
|
1034
|
+
reg_type = reg.prefix.encode(common.ENCODE)
|
1035
|
+
file_obj.write(
|
1036
|
+
struct.pack(
|
1037
|
+
formats.REGISTER_V4_PACK,
|
1038
|
+
reg_type,
|
1039
|
+
standalone,
|
1040
|
+
reg.size,
|
1041
|
+
len(reg_name),
|
1042
|
+
is_in_circuit,
|
1043
|
+
)
|
1044
|
+
)
|
1045
|
+
file_obj.write(reg_name)
|
1046
|
+
REGISTER_ARRAY_PACK = f"!{reg.size}q"
|
1047
|
+
bit_indices = []
|
1048
|
+
for bit in reg:
|
1049
|
+
bit_indices.append(bitmap.get(bit, -1))
|
1050
|
+
file_obj.write(struct.pack(REGISTER_ARRAY_PACK, *bit_indices))
|
1051
|
+
|
1052
|
+
return len(in_circ_regs) + len(out_circ_regs)
|
1053
|
+
|
1054
|
+
|
1055
|
+
def _write_layout(file_obj, circuit):
|
1056
|
+
if circuit.layout is None:
|
1057
|
+
# Write a null header if there is no layout present
|
1058
|
+
file_obj.write(struct.pack(formats.LAYOUT_V2_PACK, False, -1, -1, -1, 0, 0))
|
1059
|
+
return
|
1060
|
+
initial_size = -1
|
1061
|
+
input_qubit_mapping = {}
|
1062
|
+
initial_layout_array = []
|
1063
|
+
extra_registers = defaultdict(list)
|
1064
|
+
if circuit.layout.initial_layout is not None:
|
1065
|
+
initial_size = len(circuit.layout.initial_layout)
|
1066
|
+
layout_mapping = circuit.layout.initial_layout.get_physical_bits()
|
1067
|
+
for i in range(circuit.num_qubits):
|
1068
|
+
qubit = layout_mapping[i]
|
1069
|
+
input_qubit_mapping[qubit] = i
|
1070
|
+
if qubit._register is not None or qubit._index is not None:
|
1071
|
+
if qubit._register not in circuit.qregs:
|
1072
|
+
extra_registers[qubit._register].append(qubit)
|
1073
|
+
initial_layout_array.append((qubit._index, qubit._register))
|
1074
|
+
else:
|
1075
|
+
initial_layout_array.append((None, None))
|
1076
|
+
input_qubit_size = -1
|
1077
|
+
input_qubit_mapping_array = []
|
1078
|
+
if circuit.layout.input_qubit_mapping is not None:
|
1079
|
+
input_qubit_size = len(circuit.layout.input_qubit_mapping)
|
1080
|
+
input_qubit_mapping_array = [None] * input_qubit_size
|
1081
|
+
layout_mapping = circuit.layout.initial_layout.get_virtual_bits()
|
1082
|
+
for qubit, index in circuit.layout.input_qubit_mapping.items():
|
1083
|
+
if (
|
1084
|
+
getattr(qubit, "_register", None) is not None
|
1085
|
+
and getattr(qubit, "_index", None) is not None
|
1086
|
+
):
|
1087
|
+
if qubit._register not in circuit.qregs:
|
1088
|
+
extra_registers[qubit._register].append(qubit)
|
1089
|
+
input_qubit_mapping_array[index] = layout_mapping[qubit]
|
1090
|
+
else:
|
1091
|
+
input_qubit_mapping_array[index] = layout_mapping[qubit]
|
1092
|
+
final_layout_size = -1
|
1093
|
+
final_layout_array = []
|
1094
|
+
if circuit.layout.final_layout is not None:
|
1095
|
+
final_layout_size = len(circuit.layout.final_layout)
|
1096
|
+
final_layout_physical = circuit.layout.final_layout.get_physical_bits()
|
1097
|
+
for i in range(circuit.num_qubits):
|
1098
|
+
virtual_bit = final_layout_physical[i]
|
1099
|
+
final_layout_array.append(circuit.find_bit(virtual_bit).index)
|
1100
|
+
|
1101
|
+
input_qubit_count = circuit._layout._input_qubit_count
|
1102
|
+
if input_qubit_count is None:
|
1103
|
+
input_qubit_count = -1
|
1104
|
+
file_obj.write(
|
1105
|
+
struct.pack(
|
1106
|
+
formats.LAYOUT_V2_PACK,
|
1107
|
+
True,
|
1108
|
+
initial_size,
|
1109
|
+
input_qubit_size,
|
1110
|
+
final_layout_size,
|
1111
|
+
len(extra_registers),
|
1112
|
+
input_qubit_count,
|
1113
|
+
)
|
1114
|
+
)
|
1115
|
+
_write_registers(
|
1116
|
+
file_obj, list(extra_registers), [x for bits in extra_registers.values() for x in bits]
|
1117
|
+
)
|
1118
|
+
for index, register in initial_layout_array:
|
1119
|
+
reg_name_bytes = None if register is None else register.name.encode(common.ENCODE)
|
1120
|
+
file_obj.write(
|
1121
|
+
struct.pack(
|
1122
|
+
formats.INITIAL_LAYOUT_BIT_PACK,
|
1123
|
+
-1 if index is None else index,
|
1124
|
+
-1 if reg_name_bytes is None else len(reg_name_bytes),
|
1125
|
+
)
|
1126
|
+
)
|
1127
|
+
if reg_name_bytes is not None:
|
1128
|
+
file_obj.write(reg_name_bytes)
|
1129
|
+
for i in input_qubit_mapping_array:
|
1130
|
+
file_obj.write(struct.pack("!I", i))
|
1131
|
+
for i in final_layout_array:
|
1132
|
+
file_obj.write(struct.pack("!I", i))
|
1133
|
+
|
1134
|
+
|
1135
|
+
def _read_layout(file_obj, circuit):
|
1136
|
+
header = formats.LAYOUT._make(
|
1137
|
+
struct.unpack(formats.LAYOUT_PACK, file_obj.read(formats.LAYOUT_SIZE))
|
1138
|
+
)
|
1139
|
+
if not header.exists:
|
1140
|
+
return
|
1141
|
+
_read_common_layout(file_obj, header, circuit)
|
1142
|
+
|
1143
|
+
|
1144
|
+
def _read_common_layout(file_obj, header, circuit):
|
1145
|
+
registers = {
|
1146
|
+
name: QuantumRegister(len(v[1]), name)
|
1147
|
+
for name, v in _read_registers_v4(file_obj, header.extra_registers)["q"].items()
|
1148
|
+
}
|
1149
|
+
initial_layout = None
|
1150
|
+
initial_layout_virtual_bits = []
|
1151
|
+
for _ in range(header.initial_layout_size):
|
1152
|
+
virtual_bit = formats.INITIAL_LAYOUT_BIT._make(
|
1153
|
+
struct.unpack(
|
1154
|
+
formats.INITIAL_LAYOUT_BIT_PACK,
|
1155
|
+
file_obj.read(formats.INITIAL_LAYOUT_BIT_SIZE),
|
1156
|
+
)
|
1157
|
+
)
|
1158
|
+
if virtual_bit.index == -1 and virtual_bit.register_size == -1:
|
1159
|
+
qubit = Qubit()
|
1160
|
+
else:
|
1161
|
+
register_name = file_obj.read(virtual_bit.register_size).decode(common.ENCODE)
|
1162
|
+
if register_name in registers:
|
1163
|
+
qubit = registers[register_name][virtual_bit.index]
|
1164
|
+
else:
|
1165
|
+
register = next(filter(lambda x, name=register_name: x.name == name, circuit.qregs))
|
1166
|
+
qubit = register[virtual_bit.index]
|
1167
|
+
initial_layout_virtual_bits.append(qubit)
|
1168
|
+
if initial_layout_virtual_bits:
|
1169
|
+
initial_layout = Layout.from_qubit_list(initial_layout_virtual_bits)
|
1170
|
+
input_qubit_mapping = None
|
1171
|
+
input_qubit_mapping_array = []
|
1172
|
+
for _ in range(header.input_mapping_size):
|
1173
|
+
input_qubit_mapping_array.append(
|
1174
|
+
struct.unpack("!I", file_obj.read(struct.calcsize("!I")))[0]
|
1175
|
+
)
|
1176
|
+
if input_qubit_mapping_array:
|
1177
|
+
input_qubit_mapping = {}
|
1178
|
+
physical_bits = initial_layout.get_physical_bits()
|
1179
|
+
for index, bit in enumerate(input_qubit_mapping_array):
|
1180
|
+
input_qubit_mapping[physical_bits[bit]] = index
|
1181
|
+
final_layout = None
|
1182
|
+
final_layout_array = []
|
1183
|
+
for _ in range(header.final_layout_size):
|
1184
|
+
final_layout_array.append(struct.unpack("!I", file_obj.read(struct.calcsize("!I")))[0])
|
1185
|
+
|
1186
|
+
if final_layout_array:
|
1187
|
+
layout_dict = {circuit.qubits[bit]: index for index, bit in enumerate(final_layout_array)}
|
1188
|
+
final_layout = Layout(layout_dict)
|
1189
|
+
|
1190
|
+
circuit._layout = TranspileLayout(initial_layout, input_qubit_mapping, final_layout)
|
1191
|
+
|
1192
|
+
|
1193
|
+
def _read_layout_v2(file_obj, circuit):
|
1194
|
+
header = formats.LAYOUT_V2._make(
|
1195
|
+
struct.unpack(formats.LAYOUT_V2_PACK, file_obj.read(formats.LAYOUT_V2_SIZE))
|
1196
|
+
)
|
1197
|
+
if not header.exists:
|
1198
|
+
return
|
1199
|
+
_read_common_layout(file_obj, header, circuit)
|
1200
|
+
if header.input_qubit_count >= 0:
|
1201
|
+
circuit._layout._input_qubit_count = header.input_qubit_count
|
1202
|
+
circuit._layout._output_qubit_list = circuit.qubits
|
1203
|
+
|
1204
|
+
|
1205
|
+
def write_circuit(
|
1206
|
+
file_obj, circuit, metadata_serializer=None, use_symengine=False, version=common.QPY_VERSION
|
1207
|
+
):
|
1208
|
+
"""Write a single QuantumCircuit object in the file like object.
|
1209
|
+
|
1210
|
+
Args:
|
1211
|
+
file_obj (FILE): The file like object to write the circuit data in.
|
1212
|
+
circuit (QuantumCircuit): The circuit data to write.
|
1213
|
+
metadata_serializer (JSONEncoder): An optional JSONEncoder class that
|
1214
|
+
will be passed the :attr:`.QuantumCircuit.metadata` dictionary for
|
1215
|
+
``circuit`` and will be used as the ``cls`` kwarg
|
1216
|
+
on the ``json.dump()`` call to JSON serialize that dictionary.
|
1217
|
+
use_symengine (bool): If True, symbolic objects will be serialized using symengine's
|
1218
|
+
native mechanism. This is a faster serialization alternative, but not supported in all
|
1219
|
+
platforms. Please check that your target platform is supported by the symengine library
|
1220
|
+
before setting this option, as it will be required by qpy to deserialize the payload.
|
1221
|
+
version (int): The QPY format version to use for serializing this circuit
|
1222
|
+
"""
|
1223
|
+
metadata_raw = json.dumps(
|
1224
|
+
circuit.metadata, separators=(",", ":"), cls=metadata_serializer
|
1225
|
+
).encode(common.ENCODE)
|
1226
|
+
metadata_size = len(metadata_raw)
|
1227
|
+
num_instructions = len(circuit)
|
1228
|
+
circuit_name = circuit.name.encode(common.ENCODE)
|
1229
|
+
global_phase_type, global_phase_data = value.dumps_value(circuit.global_phase, version=version)
|
1230
|
+
|
1231
|
+
with io.BytesIO() as reg_buf:
|
1232
|
+
num_qregs = _write_registers(reg_buf, circuit.qregs, circuit.qubits)
|
1233
|
+
num_cregs = _write_registers(reg_buf, circuit.cregs, circuit.clbits)
|
1234
|
+
registers_raw = reg_buf.getvalue()
|
1235
|
+
num_registers = num_qregs + num_cregs
|
1236
|
+
|
1237
|
+
# Write circuit header
|
1238
|
+
header_raw = formats.CIRCUIT_HEADER_V12(
|
1239
|
+
name_size=len(circuit_name),
|
1240
|
+
global_phase_type=global_phase_type,
|
1241
|
+
global_phase_size=len(global_phase_data),
|
1242
|
+
num_qubits=circuit.num_qubits,
|
1243
|
+
num_clbits=circuit.num_clbits,
|
1244
|
+
metadata_size=metadata_size,
|
1245
|
+
num_registers=num_registers,
|
1246
|
+
num_instructions=num_instructions,
|
1247
|
+
num_vars=circuit.num_identifiers,
|
1248
|
+
)
|
1249
|
+
header = struct.pack(formats.CIRCUIT_HEADER_V12_PACK, *header_raw)
|
1250
|
+
file_obj.write(header)
|
1251
|
+
file_obj.write(circuit_name)
|
1252
|
+
file_obj.write(global_phase_data)
|
1253
|
+
file_obj.write(metadata_raw)
|
1254
|
+
# Write header payload
|
1255
|
+
file_obj.write(registers_raw)
|
1256
|
+
standalone_var_indices = value.write_standalone_vars(file_obj, circuit, version)
|
1257
|
+
|
1258
|
+
instruction_buffer = io.BytesIO()
|
1259
|
+
custom_operations = {}
|
1260
|
+
index_map = {}
|
1261
|
+
index_map["q"] = {bit: index for index, bit in enumerate(circuit.qubits)}
|
1262
|
+
index_map["c"] = {bit: index for index, bit in enumerate(circuit.clbits)}
|
1263
|
+
for instruction in circuit.data:
|
1264
|
+
_write_instruction(
|
1265
|
+
instruction_buffer,
|
1266
|
+
instruction,
|
1267
|
+
custom_operations,
|
1268
|
+
index_map,
|
1269
|
+
use_symengine,
|
1270
|
+
version,
|
1271
|
+
standalone_var_indices=standalone_var_indices,
|
1272
|
+
)
|
1273
|
+
|
1274
|
+
with io.BytesIO() as custom_operations_buffer:
|
1275
|
+
new_custom_operations = list(custom_operations.keys())
|
1276
|
+
while new_custom_operations:
|
1277
|
+
operations_to_serialize = new_custom_operations.copy()
|
1278
|
+
new_custom_operations = []
|
1279
|
+
for name in operations_to_serialize:
|
1280
|
+
operation = custom_operations[name]
|
1281
|
+
new_custom_operations.extend(
|
1282
|
+
_write_custom_operation(
|
1283
|
+
custom_operations_buffer,
|
1284
|
+
name,
|
1285
|
+
operation,
|
1286
|
+
custom_operations,
|
1287
|
+
use_symengine,
|
1288
|
+
version,
|
1289
|
+
standalone_var_indices=standalone_var_indices,
|
1290
|
+
)
|
1291
|
+
)
|
1292
|
+
|
1293
|
+
file_obj.write(struct.pack(formats.CUSTOM_CIRCUIT_DEF_HEADER_PACK, len(custom_operations)))
|
1294
|
+
file_obj.write(custom_operations_buffer.getvalue())
|
1295
|
+
|
1296
|
+
file_obj.write(instruction_buffer.getvalue())
|
1297
|
+
instruction_buffer.close()
|
1298
|
+
|
1299
|
+
# Pulse has been removed in Qiskit 2.0. As long as we keep QPY at version 13,
|
1300
|
+
# we need to write an empty calibrations header since read_circuit expects it
|
1301
|
+
header = struct.pack(formats.CALIBRATION_PACK, 0)
|
1302
|
+
file_obj.write(header)
|
1303
|
+
|
1304
|
+
_write_layout(file_obj, circuit)
|
1305
|
+
|
1306
|
+
|
1307
|
+
def read_circuit(file_obj, version, metadata_deserializer=None, use_symengine=False):
|
1308
|
+
"""Read a single QuantumCircuit object from the file like object.
|
1309
|
+
|
1310
|
+
Args:
|
1311
|
+
file_obj (FILE): The file like object to read the circuit data from.
|
1312
|
+
version (int): QPY version.
|
1313
|
+
metadata_deserializer (JSONDecoder): An optional JSONDecoder class
|
1314
|
+
that will be used for the ``cls`` kwarg on the internal
|
1315
|
+
``json.load`` call used to deserialize the JSON payload used for
|
1316
|
+
the :attr:`.QuantumCircuit.metadata` attribute for a circuit
|
1317
|
+
in the file-like object. If this is not specified the circuit metadata will
|
1318
|
+
be parsed as JSON with the stdlib ``json.load()`` function using
|
1319
|
+
the default ``JSONDecoder`` class.
|
1320
|
+
use_symengine (bool): If True, symbolic objects will be de-serialized using
|
1321
|
+
symengine's native mechanism. This is a faster serialization alternative, but not
|
1322
|
+
supported in all platforms. Please check that your target platform is supported by
|
1323
|
+
the symengine library before setting this option, as it will be required by qpy to
|
1324
|
+
deserialize the payload.
|
1325
|
+
Returns:
|
1326
|
+
QuantumCircuit: The circuit object from the file.
|
1327
|
+
|
1328
|
+
Raises:
|
1329
|
+
QpyError: Invalid register.
|
1330
|
+
"""
|
1331
|
+
vectors = {}
|
1332
|
+
if version < 2:
|
1333
|
+
header, name, metadata = _read_header(file_obj, metadata_deserializer=metadata_deserializer)
|
1334
|
+
elif version < 12:
|
1335
|
+
header, name, metadata = _read_header_v2(
|
1336
|
+
file_obj, version, vectors, metadata_deserializer=metadata_deserializer
|
1337
|
+
)
|
1338
|
+
else:
|
1339
|
+
header, name, metadata = _read_header_v12(
|
1340
|
+
file_obj, version, vectors, metadata_deserializer=metadata_deserializer
|
1341
|
+
)
|
1342
|
+
|
1343
|
+
global_phase = header["global_phase"]
|
1344
|
+
num_qubits = header["num_qubits"]
|
1345
|
+
num_clbits = header["num_clbits"]
|
1346
|
+
num_registers = header["num_registers"]
|
1347
|
+
num_instructions = header["num_instructions"]
|
1348
|
+
num_identifiers = header.get("num_vars", 0)
|
1349
|
+
# `out_registers` is two "name: register" maps segregated by type for the rest of QPY, and
|
1350
|
+
# `all_registers` is the complete ordered list used to construct the `QuantumCircuit`.
|
1351
|
+
out_registers = {"q": {}, "c": {}}
|
1352
|
+
all_registers = []
|
1353
|
+
out_bits = {"q": [None] * num_qubits, "c": [None] * num_clbits}
|
1354
|
+
if num_registers > 0:
|
1355
|
+
if version < 4:
|
1356
|
+
registers = _read_registers(file_obj, num_registers)
|
1357
|
+
else:
|
1358
|
+
registers = _read_registers_v4(file_obj, num_registers)
|
1359
|
+
for bit_type_label, bit_type, reg_type in [
|
1360
|
+
("q", Qubit, QuantumRegister),
|
1361
|
+
("c", Clbit, ClassicalRegister),
|
1362
|
+
]:
|
1363
|
+
# This does two passes through the registers. In the first, we're actually just
|
1364
|
+
# constructing the `Bit` instances: any register that is `standalone` "owns" all its
|
1365
|
+
# bits in the old Qiskit data model, so we have to construct those by creating the
|
1366
|
+
# register and taking the bits from them. That's the case even if that register isn't
|
1367
|
+
# actually in the circuit, which is why we stored them (with `in_circuit=False`) in QPY.
|
1368
|
+
#
|
1369
|
+
# Since there's no guarantees in QPY about the ordering of registers, we have to pass
|
1370
|
+
# through all registers to create the bits first, because we can't reliably know if a
|
1371
|
+
# non-standalone register contains bits from a standalone one until we've seen all
|
1372
|
+
# standalone registers.
|
1373
|
+
typed_bits = out_bits[bit_type_label]
|
1374
|
+
typed_registers = registers[bit_type_label]
|
1375
|
+
for register_name, (standalone, indices, _incircuit) in typed_registers.items():
|
1376
|
+
if not standalone:
|
1377
|
+
continue
|
1378
|
+
register = reg_type(len(indices), register_name)
|
1379
|
+
out_registers[bit_type_label][register_name] = register
|
1380
|
+
for owned, index in zip(register, indices):
|
1381
|
+
# Negative indices are for bits that aren't in the circuit.
|
1382
|
+
if index >= 0:
|
1383
|
+
typed_bits[index] = owned
|
1384
|
+
# Any remaining unset bits aren't owned, so we can construct them in the standard way.
|
1385
|
+
typed_bits = [bit if bit is not None else bit_type() for bit in typed_bits]
|
1386
|
+
# Finally _properly_ construct all the registers. Bits can be in more than one
|
1387
|
+
# register, including bits that are old-style "owned" by a register.
|
1388
|
+
for register_name, (standalone, indices, in_circuit) in typed_registers.items():
|
1389
|
+
if standalone:
|
1390
|
+
register = out_registers[bit_type_label][register_name]
|
1391
|
+
else:
|
1392
|
+
register = reg_type(
|
1393
|
+
name=register_name,
|
1394
|
+
bits=[typed_bits[x] if x >= 0 else bit_type() for x in indices],
|
1395
|
+
)
|
1396
|
+
out_registers[bit_type_label][register_name] = register
|
1397
|
+
if in_circuit:
|
1398
|
+
all_registers.append(register)
|
1399
|
+
out_bits[bit_type_label] = typed_bits
|
1400
|
+
else:
|
1401
|
+
out_bits = {
|
1402
|
+
"q": [Qubit() for _ in out_bits["q"]],
|
1403
|
+
"c": [Clbit() for _ in out_bits["c"]],
|
1404
|
+
}
|
1405
|
+
var_segments, standalone_var_indices = value.read_standalone_vars(file_obj, num_identifiers)
|
1406
|
+
circ = QuantumCircuit(
|
1407
|
+
out_bits["q"],
|
1408
|
+
out_bits["c"],
|
1409
|
+
*all_registers,
|
1410
|
+
name=name,
|
1411
|
+
global_phase=global_phase,
|
1412
|
+
metadata=metadata,
|
1413
|
+
inputs=var_segments[type_keys.ExprVarDeclaration.INPUT],
|
1414
|
+
captures=itertools.chain(
|
1415
|
+
var_segments[type_keys.ExprVarDeclaration.CAPTURE],
|
1416
|
+
var_segments[type_keys.ExprVarDeclaration.STRETCH_CAPTURE],
|
1417
|
+
),
|
1418
|
+
)
|
1419
|
+
for declaration in var_segments[type_keys.ExprVarDeclaration.LOCAL]:
|
1420
|
+
circ.add_uninitialized_var(declaration)
|
1421
|
+
for stretch in var_segments[type_keys.ExprVarDeclaration.STRETCH_LOCAL]:
|
1422
|
+
circ.add_stretch(stretch)
|
1423
|
+
custom_operations = _read_custom_operations(file_obj, version, vectors)
|
1424
|
+
for _instruction in range(num_instructions):
|
1425
|
+
_read_instruction(
|
1426
|
+
file_obj,
|
1427
|
+
circ,
|
1428
|
+
out_registers,
|
1429
|
+
custom_operations,
|
1430
|
+
version,
|
1431
|
+
vectors,
|
1432
|
+
use_symengine,
|
1433
|
+
standalone_var_indices,
|
1434
|
+
)
|
1435
|
+
|
1436
|
+
# Consume calibrations, but don't use them since pulse gates are not supported as of Qiskit 2.0
|
1437
|
+
if version >= 5:
|
1438
|
+
_read_calibrations(file_obj, version, vectors, metadata_deserializer)
|
1439
|
+
|
1440
|
+
for vec_name, (vector, initialized_params) in vectors.items():
|
1441
|
+
if len(initialized_params) != len(vector):
|
1442
|
+
warnings.warn(
|
1443
|
+
f"The ParameterVector: '{vec_name}' is not fully identical to its "
|
1444
|
+
"pre-serialization state. Elements "
|
1445
|
+
f"{', '.join([str(x) for x in set(range(len(vector))) - initialized_params])} "
|
1446
|
+
"in the ParameterVector will be not equal to the pre-serialized ParameterVector "
|
1447
|
+
f"as they weren't used in the circuit: {circ.name}",
|
1448
|
+
UserWarning,
|
1449
|
+
)
|
1450
|
+
if version >= 8:
|
1451
|
+
if version >= 10:
|
1452
|
+
_read_layout_v2(file_obj, circ)
|
1453
|
+
else:
|
1454
|
+
_read_layout(file_obj, circ)
|
1455
|
+
return circ
|