qiskit 1.1.2__cp38-abi3-win32.whl → 1.2.0__cp38-abi3-win32.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 -1
- qiskit/__init__.py +27 -24
- qiskit/_accelerate.pyd +0 -0
- qiskit/_numpy_compat.py +1 -1
- qiskit/assembler/assemble_circuits.py +107 -64
- qiskit/assembler/assemble_schedules.py +5 -12
- qiskit/assembler/disassemble.py +10 -1
- qiskit/circuit/__init__.py +6 -3
- qiskit/circuit/_classical_resource_map.py +5 -5
- qiskit/circuit/_utils.py +0 -13
- qiskit/circuit/add_control.py +1 -1
- qiskit/circuit/annotated_operation.py +23 -1
- qiskit/circuit/classical/expr/expr.py +4 -4
- qiskit/circuit/classical/expr/visitors.py +1 -1
- qiskit/circuit/classical/types/__init__.py +1 -1
- qiskit/circuit/classical/types/types.py +2 -2
- qiskit/circuit/classicalfunction/boolean_expression.py +1 -1
- qiskit/circuit/classicalfunction/classical_function_visitor.py +5 -5
- qiskit/circuit/classicalfunction/utils.py +1 -1
- qiskit/circuit/classicalregister.py +1 -1
- qiskit/circuit/commutation_checker.py +83 -35
- qiskit/circuit/controlflow/_builder_utils.py +1 -1
- qiskit/circuit/controlflow/builder.py +10 -6
- qiskit/circuit/controlflow/if_else.py +2 -2
- qiskit/circuit/controlflow/switch_case.py +1 -1
- qiskit/circuit/delay.py +1 -1
- qiskit/circuit/duration.py +2 -2
- qiskit/circuit/equivalence.py +5 -7
- qiskit/circuit/gate.py +11 -8
- qiskit/circuit/instruction.py +31 -13
- qiskit/circuit/instructionset.py +2 -5
- qiskit/circuit/library/__init__.py +2 -1
- qiskit/circuit/library/arithmetic/linear_amplitude_function.py +1 -1
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +3 -3
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +1 -1
- qiskit/circuit/library/basis_change/__init__.py +1 -1
- qiskit/circuit/library/basis_change/qft.py +40 -6
- qiskit/circuit/library/blueprintcircuit.py +3 -5
- qiskit/circuit/library/data_preparation/__init__.py +9 -2
- qiskit/circuit/library/data_preparation/initializer.py +8 -0
- qiskit/circuit/library/data_preparation/state_preparation.py +98 -178
- qiskit/circuit/library/generalized_gates/isometry.py +8 -8
- qiskit/circuit/library/generalized_gates/linear_function.py +3 -2
- qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +4 -4
- qiskit/circuit/library/generalized_gates/permutation.py +8 -9
- qiskit/circuit/library/generalized_gates/uc.py +3 -3
- qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +2 -2
- qiskit/circuit/library/generalized_gates/unitary.py +13 -11
- qiskit/circuit/library/graph_state.py +1 -1
- qiskit/circuit/library/hamiltonian_gate.py +1 -2
- qiskit/circuit/library/hidden_linear_function.py +1 -1
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +3 -2
- qiskit/circuit/library/n_local/n_local.py +4 -5
- qiskit/circuit/library/n_local/pauli_two_design.py +1 -1
- qiskit/circuit/library/n_local/qaoa_ansatz.py +6 -8
- qiskit/circuit/library/n_local/two_local.py +1 -1
- qiskit/circuit/library/overlap.py +11 -5
- qiskit/circuit/library/pauli_evolution.py +7 -3
- qiskit/circuit/library/standard_gates/dcx.py +3 -0
- qiskit/circuit/library/standard_gates/ecr.py +3 -0
- qiskit/circuit/library/standard_gates/global_phase.py +3 -0
- qiskit/circuit/library/standard_gates/h.py +13 -5
- qiskit/circuit/library/standard_gates/i.py +3 -0
- qiskit/circuit/library/standard_gates/iswap.py +3 -0
- qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +19 -10
- qiskit/circuit/library/standard_gates/p.py +14 -9
- qiskit/circuit/library/standard_gates/r.py +3 -0
- qiskit/circuit/library/standard_gates/rx.py +21 -6
- qiskit/circuit/library/standard_gates/rxx.py +40 -1
- qiskit/circuit/library/standard_gates/ry.py +21 -6
- qiskit/circuit/library/standard_gates/ryy.py +40 -1
- qiskit/circuit/library/standard_gates/rz.py +22 -6
- qiskit/circuit/library/standard_gates/rzx.py +40 -1
- qiskit/circuit/library/standard_gates/rzz.py +41 -2
- qiskit/circuit/library/standard_gates/s.py +77 -0
- qiskit/circuit/library/standard_gates/swap.py +12 -5
- qiskit/circuit/library/standard_gates/sx.py +14 -5
- qiskit/circuit/library/standard_gates/t.py +5 -0
- qiskit/circuit/library/standard_gates/u.py +22 -7
- qiskit/circuit/library/standard_gates/u1.py +8 -3
- qiskit/circuit/library/standard_gates/u2.py +3 -0
- qiskit/circuit/library/standard_gates/u3.py +22 -7
- qiskit/circuit/library/standard_gates/x.py +156 -92
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +40 -1
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +52 -11
- qiskit/circuit/library/standard_gates/y.py +6 -1
- qiskit/circuit/library/standard_gates/z.py +8 -1
- qiskit/circuit/operation.py +1 -1
- qiskit/circuit/parameter.py +9 -10
- qiskit/circuit/parameterexpression.py +16 -13
- qiskit/circuit/parametertable.py +1 -190
- qiskit/circuit/parametervector.py +1 -1
- qiskit/circuit/quantumcircuit.py +395 -387
- qiskit/circuit/quantumcircuitdata.py +3 -5
- qiskit/circuit/quantumregister.py +1 -1
- qiskit/circuit/random/__init__.py +1 -1
- qiskit/circuit/random/utils.py +175 -26
- qiskit/circuit/register.py +5 -7
- qiskit/circuit/singleton.py +3 -3
- qiskit/circuit/tools/pi_check.py +4 -4
- qiskit/compiler/assembler.py +95 -24
- qiskit/compiler/scheduler.py +2 -2
- qiskit/compiler/transpiler.py +42 -128
- qiskit/converters/circuit_to_dag.py +4 -6
- qiskit/converters/circuit_to_gate.py +4 -8
- qiskit/converters/circuit_to_instruction.py +5 -17
- qiskit/converters/dag_to_circuit.py +2 -6
- qiskit/dagcircuit/collect_blocks.py +2 -2
- qiskit/dagcircuit/dagcircuit.py +190 -187
- qiskit/dagcircuit/dagdependency.py +4 -4
- qiskit/dagcircuit/dagdependency_v2.py +4 -4
- qiskit/dagcircuit/dagdepnode.py +1 -1
- qiskit/dagcircuit/dagnode.py +66 -157
- qiskit/passmanager/flow_controllers.py +1 -1
- qiskit/passmanager/passmanager.py +3 -3
- qiskit/primitives/__init__.py +1 -5
- qiskit/primitives/backend_estimator.py +25 -15
- qiskit/primitives/backend_estimator_v2.py +31 -7
- qiskit/primitives/backend_sampler.py +21 -12
- qiskit/primitives/backend_sampler_v2.py +12 -3
- qiskit/primitives/base/base_estimator.py +31 -4
- qiskit/primitives/base/base_primitive.py +2 -2
- qiskit/primitives/base/base_result.py +2 -2
- qiskit/primitives/base/base_sampler.py +26 -2
- qiskit/primitives/base/estimator_result.py +2 -2
- qiskit/primitives/base/sampler_result.py +2 -2
- qiskit/primitives/containers/__init__.py +0 -1
- qiskit/primitives/containers/bindings_array.py +2 -2
- qiskit/primitives/containers/bit_array.py +108 -10
- qiskit/primitives/containers/shape.py +3 -3
- qiskit/primitives/estimator.py +9 -2
- qiskit/primitives/primitive_job.py +1 -1
- qiskit/primitives/sampler.py +10 -3
- qiskit/primitives/statevector_estimator.py +5 -3
- qiskit/primitives/statevector_sampler.py +11 -5
- qiskit/primitives/utils.py +16 -0
- qiskit/providers/backend.py +15 -6
- qiskit/providers/backend_compat.py +7 -4
- qiskit/providers/basic_provider/basic_provider_tools.py +1 -1
- qiskit/providers/basic_provider/basic_simulator.py +33 -25
- qiskit/providers/fake_provider/fake_backend.py +10 -3
- qiskit/providers/fake_provider/fake_openpulse_2q.py +157 -149
- qiskit/providers/fake_provider/fake_openpulse_3q.py +228 -220
- qiskit/providers/fake_provider/fake_pulse_backend.py +2 -1
- qiskit/providers/fake_provider/fake_qasm_backend.py +7 -2
- qiskit/providers/fake_provider/generic_backend_v2.py +514 -68
- qiskit/providers/models/__init__.py +48 -11
- qiskit/providers/models/backendconfiguration.py +50 -4
- qiskit/providers/models/backendproperties.py +13 -2
- qiskit/providers/models/pulsedefaults.py +10 -11
- qiskit/providers/options.py +13 -13
- qiskit/providers/providerutils.py +3 -1
- qiskit/pulse/configuration.py +8 -12
- qiskit/pulse/instruction_schedule_map.py +3 -5
- qiskit/pulse/instructions/acquire.py +7 -8
- qiskit/pulse/instructions/instruction.py +2 -3
- qiskit/pulse/library/samplers/decorators.py +5 -9
- qiskit/pulse/library/symbolic_pulses.py +4 -7
- qiskit/pulse/library/waveform.py +2 -5
- qiskit/pulse/macros.py +11 -6
- qiskit/pulse/parser.py +8 -10
- qiskit/pulse/schedule.py +9 -17
- qiskit/pulse/transforms/alignments.py +1 -3
- qiskit/pulse/utils.py +1 -2
- qiskit/qasm/libs/stdgates.inc +35 -28
- qiskit/qasm2/__init__.py +7 -7
- qiskit/qasm2/export.py +5 -9
- qiskit/qasm2/parse.py +1 -1
- qiskit/qasm3/ast.py +9 -25
- qiskit/qasm3/exporter.py +582 -479
- qiskit/qasm3/printer.py +7 -16
- qiskit/qobj/common.py +10 -0
- qiskit/qobj/converters/lo_config.py +9 -0
- qiskit/qobj/converters/pulse_instruction.py +13 -6
- qiskit/qobj/pulse_qobj.py +69 -15
- qiskit/qobj/qasm_qobj.py +72 -20
- qiskit/qobj/utils.py +9 -0
- qiskit/qpy/__init__.py +1 -1
- qiskit/qpy/binary_io/circuits.py +8 -5
- qiskit/qpy/binary_io/schedules.py +1 -1
- qiskit/qpy/binary_io/value.py +3 -3
- qiskit/qpy/interface.py +3 -2
- qiskit/qpy/type_keys.py +2 -2
- qiskit/quantum_info/operators/channel/quantum_channel.py +3 -6
- qiskit/quantum_info/operators/channel/superop.py +2 -2
- qiskit/quantum_info/operators/channel/transformations.py +1 -1
- qiskit/quantum_info/operators/dihedral/dihedral.py +3 -4
- qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +1 -3
- qiskit/quantum_info/operators/dihedral/random.py +6 -3
- qiskit/quantum_info/operators/measures.py +2 -2
- qiskit/quantum_info/operators/op_shape.py +12 -20
- qiskit/quantum_info/operators/operator.py +14 -21
- qiskit/quantum_info/operators/predicates.py +1 -0
- qiskit/quantum_info/operators/symplectic/base_pauli.py +7 -11
- qiskit/quantum_info/operators/symplectic/clifford.py +1 -1
- qiskit/quantum_info/operators/symplectic/pauli.py +3 -3
- qiskit/quantum_info/operators/symplectic/pauli_list.py +9 -10
- qiskit/quantum_info/operators/symplectic/random.py +1 -1
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +15 -17
- qiskit/quantum_info/quaternion.py +1 -1
- qiskit/quantum_info/states/densitymatrix.py +5 -8
- qiskit/quantum_info/states/stabilizerstate.py +128 -37
- qiskit/quantum_info/states/statevector.py +4 -8
- qiskit/result/counts.py +2 -2
- qiskit/result/mitigation/correlated_readout_mitigator.py +2 -2
- qiskit/result/mitigation/local_readout_mitigator.py +2 -2
- qiskit/result/mitigation/utils.py +1 -3
- qiskit/result/models.py +17 -16
- qiskit/result/result.py +15 -20
- qiskit/scheduler/lowering.py +2 -2
- qiskit/synthesis/__init__.py +2 -1
- qiskit/synthesis/clifford/__init__.py +1 -1
- qiskit/synthesis/clifford/clifford_decompose_ag.py +2 -2
- qiskit/synthesis/clifford/clifford_decompose_bm.py +10 -240
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +9 -303
- qiskit/synthesis/clifford/clifford_decompose_layers.py +25 -23
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +1 -1
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +1 -1
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +1 -1
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +2 -2
- qiskit/synthesis/evolution/evolution_synthesis.py +4 -2
- qiskit/synthesis/evolution/lie_trotter.py +46 -19
- qiskit/synthesis/evolution/product_formula.py +111 -55
- qiskit/synthesis/evolution/qdrift.py +40 -10
- qiskit/synthesis/evolution/suzuki_trotter.py +43 -33
- qiskit/synthesis/linear/__init__.py +1 -0
- qiskit/synthesis/linear/cnot_synth.py +22 -96
- qiskit/synthesis/linear/linear_depth_lnn.py +8 -8
- qiskit/synthesis/linear/linear_matrix_utils.py +13 -161
- qiskit/synthesis/linear_phase/cnot_phase_synth.py +1 -1
- qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +3 -3
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +1 -1
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +29 -29
- qiskit/synthesis/permutation/permutation_full.py +5 -29
- qiskit/synthesis/permutation/permutation_lnn.py +2 -24
- qiskit/synthesis/permutation/permutation_utils.py +2 -59
- qiskit/synthesis/qft/__init__.py +1 -0
- qiskit/synthesis/qft/qft_decompose_full.py +79 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +17 -9
- qiskit/synthesis/stabilizer/stabilizer_circuit.py +6 -6
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +2 -2
- qiskit/synthesis/two_qubit/local_invariance.py +8 -38
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +48 -129
- qiskit/synthesis/unitary/aqc/cnot_structures.py +1 -1
- qiskit/synthesis/unitary/qsd.py +5 -3
- qiskit/transpiler/__init__.py +1 -0
- qiskit/transpiler/basepasses.py +1 -1
- qiskit/transpiler/coupling.py +3 -3
- qiskit/transpiler/instruction_durations.py +1 -2
- qiskit/transpiler/layout.py +3 -3
- qiskit/transpiler/passes/__init__.py +2 -0
- qiskit/transpiler/passes/basis/basis_translator.py +84 -64
- qiskit/transpiler/passes/basis/translate_parameterized.py +3 -5
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +10 -10
- qiskit/transpiler/passes/calibration/rx_builder.py +3 -3
- qiskit/transpiler/passes/calibration/rzx_builder.py +3 -3
- qiskit/transpiler/passes/layout/apply_layout.py +13 -3
- qiskit/transpiler/passes/layout/sabre_layout.py +10 -8
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +4 -1
- qiskit/transpiler/passes/layout/set_layout.py +2 -2
- qiskit/transpiler/passes/layout/vf2_layout.py +1 -1
- qiskit/transpiler/passes/layout/vf2_utils.py +3 -3
- qiskit/transpiler/passes/optimization/__init__.py +1 -0
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +2 -2
- qiskit/transpiler/passes/optimization/commutation_analysis.py +7 -10
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +35 -19
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +17 -8
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +6 -6
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +64 -41
- qiskit/transpiler/passes/optimization/optimize_1q_gates.py +1 -1
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +83 -0
- qiskit/transpiler/passes/optimization/template_matching/backward_match.py +1 -1
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +2 -2
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -1
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -2
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +1 -1
- qiskit/transpiler/passes/routing/layout_transformation.py +2 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +35 -26
- qiskit/transpiler/passes/routing/star_prerouting.py +80 -105
- qiskit/transpiler/passes/routing/stochastic_swap.py +1 -3
- qiskit/transpiler/passes/scheduling/alap.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -2
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +2 -2
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +1 -1
- qiskit/transpiler/passes/scheduling/asap.py +1 -2
- qiskit/transpiler/passes/scheduling/base_scheduler.py +5 -5
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +3 -3
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -14
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +7 -6
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +4 -3
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +211 -36
- qiskit/transpiler/passes/synthesis/plugin.py +2 -2
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +80 -40
- qiskit/transpiler/passes/utils/__init__.py +0 -1
- qiskit/transpiler/passes/utils/check_gate_direction.py +4 -4
- qiskit/transpiler/passes/utils/check_map.py +3 -6
- qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +3 -4
- qiskit/transpiler/passes/utils/error.py +2 -2
- qiskit/transpiler/passes/utils/fixed_point.py +3 -3
- qiskit/transpiler/passes/utils/gate_direction.py +1 -1
- qiskit/transpiler/passes/utils/gates_basis.py +1 -2
- qiskit/transpiler/passmanager.py +7 -6
- qiskit/transpiler/preset_passmanagers/__init__.py +4 -228
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +73 -18
- qiskit/transpiler/preset_passmanagers/common.py +3 -6
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +518 -0
- qiskit/transpiler/preset_passmanagers/level0.py +1 -1
- qiskit/transpiler/target.py +27 -8
- qiskit/user_config.py +29 -6
- qiskit/utils/classtools.py +3 -3
- qiskit/utils/deprecation.py +3 -2
- qiskit/utils/lazy_tester.py +2 -2
- qiskit/utils/optionals.py +8 -8
- qiskit/visualization/bloch.py +18 -23
- qiskit/visualization/circuit/_utils.py +34 -10
- qiskit/visualization/circuit/circuit_visualization.py +23 -16
- qiskit/visualization/circuit/latex.py +29 -27
- qiskit/visualization/circuit/matplotlib.py +4 -2
- qiskit/visualization/circuit/qcstyle.py +2 -2
- qiskit/visualization/circuit/text.py +9 -15
- qiskit/visualization/dag_visualization.py +2 -2
- qiskit/visualization/pulse_v2/core.py +1 -1
- qiskit/visualization/pulse_v2/events.py +1 -1
- qiskit/visualization/pulse_v2/generators/frame.py +3 -4
- qiskit/visualization/pulse_v2/generators/waveform.py +5 -9
- qiskit/visualization/pulse_v2/layouts.py +1 -5
- qiskit/visualization/pulse_v2/plotters/matplotlib.py +1 -2
- qiskit/visualization/state_visualization.py +5 -6
- qiskit/visualization/timeline/plotters/matplotlib.py +1 -2
- qiskit/visualization/transition_visualization.py +7 -2
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/METADATA +12 -12
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/RECORD +342 -340
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/entry_points.txt +3 -0
- qiskit/transpiler/passes/utils/block_to_matrix.py +0 -47
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/WHEEL +0 -0
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/top_level.txt +0 -0
@@ -83,7 +83,7 @@ class ClassicalFunctionVisitor(ast.NodeVisitor):
|
|
83
83
|
"""Uses ClassicalFunctionVisitor.bitops to extend self._network"""
|
84
84
|
bitop = ClassicalFunctionVisitor.bitops.get(type(op))
|
85
85
|
if not bitop:
|
86
|
-
raise ClassicalFunctionParseError("Unknown binop.op
|
86
|
+
raise ClassicalFunctionParseError(f"Unknown binop.op {op}")
|
87
87
|
binop = getattr(self._network, bitop)
|
88
88
|
|
89
89
|
left_type, left_signal = values[0]
|
@@ -112,19 +112,19 @@ class ClassicalFunctionVisitor(ast.NodeVisitor):
|
|
112
112
|
operand_type, operand_signal = self.visit(node.operand)
|
113
113
|
if operand_type != "Int1":
|
114
114
|
raise ClassicalFunctionCompilerTypeError(
|
115
|
-
"UntaryOp.op
|
115
|
+
f"UntaryOp.op {node.op} only support operation on Int1s for now"
|
116
116
|
)
|
117
117
|
bitop = ClassicalFunctionVisitor.bitops.get(type(node.op))
|
118
118
|
if not bitop:
|
119
119
|
raise ClassicalFunctionCompilerTypeError(
|
120
|
-
"UntaryOp.op
|
120
|
+
f"UntaryOp.op {node.op} does not operate with Int1 type "
|
121
121
|
)
|
122
122
|
return "Int1", getattr(self._network, bitop)(operand_signal)
|
123
123
|
|
124
124
|
def visit_Name(self, node):
|
125
125
|
"""Reduce variable names."""
|
126
126
|
if node.id not in self.scopes[-1]:
|
127
|
-
raise ClassicalFunctionParseError("out of scope:
|
127
|
+
raise ClassicalFunctionParseError(f"out of scope: {node.id}")
|
128
128
|
return self.scopes[-1][node.id]
|
129
129
|
|
130
130
|
def generic_visit(self, node):
|
@@ -143,7 +143,7 @@ class ClassicalFunctionVisitor(ast.NodeVisitor):
|
|
143
143
|
),
|
144
144
|
):
|
145
145
|
return super().generic_visit(node)
|
146
|
-
raise ClassicalFunctionParseError("Unknown node:
|
146
|
+
raise ClassicalFunctionParseError(f"Unknown node: {type(node)}")
|
147
147
|
|
148
148
|
def extend_scope(self, args_node: _ast.arguments) -> None:
|
149
149
|
"""Add the arguments to the scope"""
|
@@ -47,7 +47,7 @@ def _convert_tweedledum_operator(op):
|
|
47
47
|
if op.kind() == "py_operator":
|
48
48
|
return op.py_op()
|
49
49
|
else:
|
50
|
-
raise RuntimeError("Unrecognized operator:
|
50
|
+
raise RuntimeError(f"Unrecognized operator: {op.kind()}")
|
51
51
|
|
52
52
|
# TODO: need to deal with cbits too!
|
53
53
|
if op.num_controls() > 0:
|
@@ -43,7 +43,7 @@ class Clbit(Bit):
|
|
43
43
|
super().__init__(register, index)
|
44
44
|
else:
|
45
45
|
raise CircuitError(
|
46
|
-
"Clbit needs a ClassicalRegister and
|
46
|
+
f"Clbit needs a ClassicalRegister and {type(register).__name__} was provided"
|
47
47
|
)
|
48
48
|
|
49
49
|
|
@@ -13,7 +13,7 @@
|
|
13
13
|
"""Code from commutative_analysis pass that checks commutation relations between DAG nodes."""
|
14
14
|
|
15
15
|
from functools import lru_cache
|
16
|
-
from typing import List, Union
|
16
|
+
from typing import List, Union, Set, Optional
|
17
17
|
import numpy as np
|
18
18
|
|
19
19
|
from qiskit import QiskitError
|
@@ -25,6 +25,27 @@ from qiskit.quantum_info.operators import Operator
|
|
25
25
|
_skipped_op_names = {"measure", "reset", "delay", "initialize"}
|
26
26
|
_no_cache_op_names = {"annotated"}
|
27
27
|
|
28
|
+
_supported_ops = {
|
29
|
+
"h",
|
30
|
+
"x",
|
31
|
+
"y",
|
32
|
+
"z",
|
33
|
+
"sx",
|
34
|
+
"sxdg",
|
35
|
+
"t",
|
36
|
+
"tdg",
|
37
|
+
"s",
|
38
|
+
"sdg",
|
39
|
+
"cx",
|
40
|
+
"cy",
|
41
|
+
"cz",
|
42
|
+
"swap",
|
43
|
+
"iswap",
|
44
|
+
"ecr",
|
45
|
+
"ccx",
|
46
|
+
"cswap",
|
47
|
+
}
|
48
|
+
|
28
49
|
|
29
50
|
@lru_cache(maxsize=None)
|
30
51
|
def _identity_op(num_qubits):
|
@@ -42,7 +63,13 @@ class CommutationChecker:
|
|
42
63
|
evicting from the cache less useful entries, etc.
|
43
64
|
"""
|
44
65
|
|
45
|
-
def __init__(
|
66
|
+
def __init__(
|
67
|
+
self,
|
68
|
+
standard_gate_commutations: dict = None,
|
69
|
+
cache_max_entries: int = 10**6,
|
70
|
+
*,
|
71
|
+
gates: Optional[Set[str]] = None,
|
72
|
+
):
|
46
73
|
super().__init__()
|
47
74
|
if standard_gate_commutations is None:
|
48
75
|
self._standard_commutations = {}
|
@@ -56,6 +83,24 @@ class CommutationChecker:
|
|
56
83
|
self._current_cache_entries = 0
|
57
84
|
self._cache_miss = 0
|
58
85
|
self._cache_hit = 0
|
86
|
+
self._gate_names = gates
|
87
|
+
|
88
|
+
def commute_nodes(
|
89
|
+
self,
|
90
|
+
op1,
|
91
|
+
op2,
|
92
|
+
max_num_qubits: int = 3,
|
93
|
+
) -> bool:
|
94
|
+
"""Checks if two DAGOpNodes commute."""
|
95
|
+
qargs1 = op1.qargs
|
96
|
+
cargs1 = op2.cargs
|
97
|
+
if not op1.is_standard_gate():
|
98
|
+
op1 = op1.op
|
99
|
+
qargs2 = op2.qargs
|
100
|
+
cargs2 = op2.cargs
|
101
|
+
if not op2.is_standard_gate():
|
102
|
+
op2 = op2.op
|
103
|
+
return self.commute(op1, qargs1, cargs1, op2, qargs2, cargs2, max_num_qubits)
|
59
104
|
|
60
105
|
def commute(
|
61
106
|
self,
|
@@ -86,6 +131,11 @@ class CommutationChecker:
|
|
86
131
|
Returns:
|
87
132
|
bool: whether two operations commute.
|
88
133
|
"""
|
134
|
+
# Skip gates that are not specified.
|
135
|
+
if self._gate_names is not None:
|
136
|
+
if op1.name not in self._gate_names or op2.name not in self._gate_names:
|
137
|
+
return False
|
138
|
+
|
89
139
|
structural_commutation = _commutation_precheck(
|
90
140
|
op1, qargs1, cargs1, op2, qargs2, cargs2, max_num_qubits
|
91
141
|
)
|
@@ -214,53 +264,38 @@ def _hashable_parameters(params):
|
|
214
264
|
return ("fallback", str(params))
|
215
265
|
|
216
266
|
|
217
|
-
def is_commutation_supported(op):
|
267
|
+
def is_commutation_supported(op, qargs, max_num_qubits):
|
218
268
|
"""
|
219
269
|
Filter operations whose commutation is not supported due to bugs in transpiler passes invoking
|
220
270
|
commutation analysis.
|
221
271
|
Args:
|
222
|
-
op (Operation): operation to be checked for commutation relation
|
272
|
+
op (Operation): operation to be checked for commutation relation.
|
273
|
+
qargs (list[Qubit]): qubits the operation acts on.
|
274
|
+
max_num_qubits (int): The maximum number of qubits to check commutativity for.
|
275
|
+
|
223
276
|
Return:
|
224
277
|
True if determining the commutation of op is currently supported
|
225
278
|
"""
|
226
|
-
#
|
227
|
-
|
279
|
+
# If the number of qubits is beyond what we check, stop here and do not even check in the
|
280
|
+
# pre-defined supported operations
|
281
|
+
if len(qargs) > max_num_qubits:
|
228
282
|
return False
|
229
283
|
|
284
|
+
# Check if the operation is pre-approved, otherwise go through the checks
|
285
|
+
if op.name in _supported_ops:
|
286
|
+
return True
|
287
|
+
|
230
288
|
# Commutation of ControlFlow gates also not supported yet. This may be pending a control flow graph.
|
231
289
|
if op.name in CONTROL_FLOW_OP_NAMES:
|
232
290
|
return False
|
233
291
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
def is_commutation_skipped(op, qargs, max_num_qubits):
|
238
|
-
"""
|
239
|
-
Filter operations whose commutation will not be determined.
|
240
|
-
Args:
|
241
|
-
op (Operation): operation to be checked for commutation relation
|
242
|
-
qargs (List): operation qubits
|
243
|
-
max_num_qubits (int): the maximum number of qubits to consider, the check may be skipped if
|
244
|
-
the number of qubits for either operation exceeds this amount.
|
245
|
-
Return:
|
246
|
-
True if determining the commutation of op is currently not supported
|
247
|
-
"""
|
248
|
-
if (
|
249
|
-
len(qargs) > max_num_qubits
|
250
|
-
or getattr(op, "_directive", False)
|
251
|
-
or op.name in _skipped_op_names
|
252
|
-
):
|
253
|
-
return True
|
292
|
+
if getattr(op, "_directive", False) or op.name in _skipped_op_names:
|
293
|
+
return False
|
254
294
|
|
255
295
|
if getattr(op, "is_parameterized", False) and op.is_parameterized():
|
256
|
-
return True
|
257
|
-
|
258
|
-
# we can proceed if op has defined: to_operator, to_matrix and __array__, or if its definition can be
|
259
|
-
# recursively resolved by operations that have a matrix. We check this by constructing an Operator.
|
260
|
-
if (hasattr(op, "to_matrix") and hasattr(op, "__array__")) or hasattr(op, "to_operator"):
|
261
296
|
return False
|
262
297
|
|
263
|
-
return
|
298
|
+
return True
|
264
299
|
|
265
300
|
|
266
301
|
def _commutation_precheck(
|
@@ -272,13 +307,14 @@ def _commutation_precheck(
|
|
272
307
|
cargs2: List,
|
273
308
|
max_num_qubits,
|
274
309
|
):
|
275
|
-
|
310
|
+
# Bug in CommutativeCancellation, e.g. see gh-8553
|
311
|
+
if getattr(op1, "condition", False) or getattr(op2, "condition", False):
|
276
312
|
return False
|
277
313
|
|
278
314
|
if set(qargs1).isdisjoint(qargs2) and set(cargs1).isdisjoint(cargs2):
|
279
315
|
return True
|
280
316
|
|
281
|
-
if
|
317
|
+
if not is_commutation_supported(op1, qargs1, max_num_qubits) or not is_commutation_supported(
|
282
318
|
op2, qargs2, max_num_qubits
|
283
319
|
):
|
284
320
|
return False
|
@@ -386,7 +422,10 @@ def _query_commutation(
|
|
386
422
|
first_params = getattr(first_op, "params", [])
|
387
423
|
second_params = getattr(second_op, "params", [])
|
388
424
|
return commutation_after_placement.get(
|
389
|
-
(
|
425
|
+
(
|
426
|
+
_hashable_parameters(first_params),
|
427
|
+
_hashable_parameters(second_params),
|
428
|
+
),
|
390
429
|
None,
|
391
430
|
)
|
392
431
|
else:
|
@@ -409,6 +448,15 @@ def _commute_matmul(
|
|
409
448
|
first_qarg = tuple(qarg[q] for q in first_qargs)
|
410
449
|
second_qarg = tuple(qarg[q] for q in second_qargs)
|
411
450
|
|
451
|
+
from qiskit.dagcircuit.dagnode import DAGOpNode
|
452
|
+
|
453
|
+
# If we have a DAGOpNode here we've received a StandardGate definition from
|
454
|
+
# rust and we can manually pull the matrix to use for the Operators
|
455
|
+
if isinstance(first_ops, DAGOpNode):
|
456
|
+
first_ops = first_ops.matrix
|
457
|
+
if isinstance(second_op, DAGOpNode):
|
458
|
+
second_op = second_op.matrix
|
459
|
+
|
412
460
|
# try to generate an Operator out of op, if this succeeds we can determine commutativity, otherwise
|
413
461
|
# return false
|
414
462
|
try:
|
@@ -127,7 +127,7 @@ def unify_circuit_resources(circuits: Iterable[QuantumCircuit]) -> Iterable[Quan
|
|
127
127
|
This function will preferentially try to mutate its inputs if they share an ordering, but if
|
128
128
|
not, it will rebuild two new circuits. This is to avoid coupling too tightly to the inner
|
129
129
|
class; there is no real support for deleting or re-ordering bits within a :obj:`.QuantumCircuit`
|
130
|
-
context, and we don't want to rely on the *current*
|
130
|
+
context, and we don't want to rely on the *current* behavior of the private APIs, since they
|
131
131
|
are very liable to change. No matter the method used, circuits with unified bits and registers
|
132
132
|
are returned.
|
133
133
|
"""
|
@@ -13,7 +13,7 @@
|
|
13
13
|
"""Builder types for the basic control-flow constructs."""
|
14
14
|
|
15
15
|
# This file is in circuit.controlflow rather than the root of circuit because the constructs here
|
16
|
-
# are only intended to be
|
16
|
+
# are only intended to be localized to constructing the control flow instructions. We anticipate
|
17
17
|
# having a far more complete builder of all circuits, with more classical control and creation, in
|
18
18
|
# the future.
|
19
19
|
|
@@ -57,7 +57,9 @@ class CircuitScopeInterface(abc.ABC):
|
|
57
57
|
"""Indexable view onto the :class:`.CircuitInstruction`s backing this scope."""
|
58
58
|
|
59
59
|
@abc.abstractmethod
|
60
|
-
def append(
|
60
|
+
def append(
|
61
|
+
self, instruction: CircuitInstruction, *, _standard_gate=False
|
62
|
+
) -> CircuitInstruction:
|
61
63
|
"""Low-level 'append' primitive; this may assume that the qubits, clbits and operation are
|
62
64
|
all valid for the circuit.
|
63
65
|
|
@@ -204,7 +206,7 @@ class InstructionPlaceholder(Instruction, abc.ABC):
|
|
204
206
|
When appending a placeholder instruction into a circuit scope, you should create the
|
205
207
|
placeholder, and then ask it what resources it should be considered as using from the start by
|
206
208
|
calling :meth:`.InstructionPlaceholder.placeholder_instructions`. This set will be a subset of
|
207
|
-
the final resources it asks for, but it is used for
|
209
|
+
the final resources it asks for, but it is used for initializing resources that *must* be
|
208
210
|
supplied, such as the bits used in the conditions of placeholder ``if`` statements.
|
209
211
|
|
210
212
|
.. warning::
|
@@ -358,7 +360,7 @@ class ControlFlowBuilderBlock(CircuitScopeInterface):
|
|
358
360
|
which use a classical register as their condition.
|
359
361
|
allow_jumps: Whether this builder scope should allow ``break`` and ``continue``
|
360
362
|
statements within it. This is intended to help give sensible error messages when
|
361
|
-
dangerous
|
363
|
+
dangerous behavior is encountered, such as using ``break`` inside an ``if`` context
|
362
364
|
manager that is not within a ``for`` manager. This can only be safe if the user is
|
363
365
|
going to place the resulting :obj:`.QuantumCircuit` inside a :obj:`.ForLoopOp` that
|
364
366
|
uses *exactly* the same set of resources. We cannot verify this from within the
|
@@ -393,7 +395,7 @@ class ControlFlowBuilderBlock(CircuitScopeInterface):
|
|
393
395
|
def allow_jumps(self):
|
394
396
|
"""Whether this builder scope should allow ``break`` and ``continue`` statements within it.
|
395
397
|
|
396
|
-
This is intended to help give sensible error messages when dangerous
|
398
|
+
This is intended to help give sensible error messages when dangerous behavior is
|
397
399
|
encountered, such as using ``break`` inside an ``if`` context manager that is not within a
|
398
400
|
``for`` manager. This can only be safe if the user is going to place the resulting
|
399
401
|
:obj:`.QuantumCircuit` inside a :obj:`.ForLoopOp` that uses *exactly* the same set of
|
@@ -420,7 +422,9 @@ class ControlFlowBuilderBlock(CircuitScopeInterface):
|
|
420
422
|
" because it is not in a loop."
|
421
423
|
)
|
422
424
|
|
423
|
-
def append(
|
425
|
+
def append(
|
426
|
+
self, instruction: CircuitInstruction, *, _standard_gate: bool = False
|
427
|
+
) -> CircuitInstruction:
|
424
428
|
if self._forbidden_message is not None:
|
425
429
|
raise CircuitError(self._forbidden_message)
|
426
430
|
if not self._allow_jumps:
|
@@ -199,7 +199,7 @@ class IfElsePlaceholder(InstructionPlaceholder):
|
|
199
199
|
super().__init__(
|
200
200
|
"if_else", len(self.__resources.qubits), len(self.__resources.clbits), [], label=label
|
201
201
|
)
|
202
|
-
# Set the condition after super().__init__() has
|
202
|
+
# Set the condition after super().__init__() has initialized it to None.
|
203
203
|
self.condition = validate_condition(condition)
|
204
204
|
|
205
205
|
def with_false_block(self, false_block: ControlFlowBuilderBlock) -> "IfElsePlaceholder":
|
@@ -236,7 +236,7 @@ class IfElsePlaceholder(InstructionPlaceholder):
|
|
236
236
|
def _calculate_placeholder_resources(self) -> InstructionResources:
|
237
237
|
"""Get the placeholder resources (see :meth:`.placeholder_resources`).
|
238
238
|
|
239
|
-
This is a separate function because we use the resources during the
|
239
|
+
This is a separate function because we use the resources during the initialization to
|
240
240
|
determine how we should set our ``num_qubits`` and ``num_clbits``, so we implement the
|
241
241
|
public version as a cache access for efficiency.
|
242
242
|
"""
|
@@ -94,7 +94,7 @@ class SwitchCaseOp(ControlFlowOp):
|
|
94
94
|
it's easier for things like `assign_parameters`, which need to touch each circuit object
|
95
95
|
exactly once, to function."""
|
96
96
|
self._label_spec: List[Tuple[Union[int, Literal[CASE_DEFAULT]], ...]] = []
|
97
|
-
"""List of the
|
97
|
+
"""List of the normalized jump value specifiers. This is a list of tuples, where each tuple
|
98
98
|
contains the values, and the indexing is the same as the values of `_case_map` and
|
99
99
|
`_params`."""
|
100
100
|
self._params = []
|
qiskit/circuit/delay.py
CHANGED
@@ -32,7 +32,7 @@ class Delay(Instruction):
|
|
32
32
|
unit: the unit of the duration. Must be ``"dt"`` or an SI-prefixed seconds unit.
|
33
33
|
"""
|
34
34
|
if unit not in {"s", "ms", "us", "ns", "ps", "dt"}:
|
35
|
-
raise CircuitError("Unknown unit
|
35
|
+
raise CircuitError(f"Unknown unit {unit} is specified.")
|
36
36
|
|
37
37
|
super().__init__("delay", 1, 0, params=[duration], unit=unit)
|
38
38
|
|
qiskit/circuit/duration.py
CHANGED
@@ -35,8 +35,8 @@ def duration_in_dt(duration_in_sec: float, dt_in_sec: float) -> int:
|
|
35
35
|
rounding_error = abs(duration_in_sec - res * dt_in_sec)
|
36
36
|
if rounding_error > 1e-15:
|
37
37
|
warnings.warn(
|
38
|
-
"Duration is rounded to
|
39
|
-
|
38
|
+
f"Duration is rounded to {res:d} [dt] = {res * dt_in_sec:e} [s] "
|
39
|
+
f"from {duration_in_sec:e} [s]",
|
40
40
|
UserWarning,
|
41
41
|
)
|
42
42
|
return res
|
qiskit/circuit/equivalence.py
CHANGED
@@ -249,7 +249,7 @@ class EquivalenceLibrary:
|
|
249
249
|
)
|
250
250
|
node_map[decomp_basis] = decomp_basis_node
|
251
251
|
|
252
|
-
label = "{}\n{
|
252
|
+
label = f"{str(params)}\n{str(decomp) if num_qubits <= 5 else '...'}"
|
253
253
|
graph.add_edge(
|
254
254
|
node_map[basis],
|
255
255
|
node_map[decomp_basis],
|
@@ -273,8 +273,8 @@ def _raise_if_param_mismatch(gate_params, circuit_parameters):
|
|
273
273
|
if set(gate_parameters) != circuit_parameters:
|
274
274
|
raise CircuitError(
|
275
275
|
"Cannot add equivalence between circuit and gate "
|
276
|
-
"of different parameters. Gate params: {}. "
|
277
|
-
"Circuit params: {}."
|
276
|
+
f"of different parameters. Gate params: {gate_parameters}. "
|
277
|
+
f"Circuit params: {circuit_parameters}."
|
278
278
|
)
|
279
279
|
|
280
280
|
|
@@ -282,10 +282,8 @@ def _raise_if_shape_mismatch(gate, circuit):
|
|
282
282
|
if gate.num_qubits != circuit.num_qubits or gate.num_clbits != circuit.num_clbits:
|
283
283
|
raise CircuitError(
|
284
284
|
"Cannot add equivalence between circuit and gate "
|
285
|
-
"of different shapes. Gate: {} qubits and {} clbits. "
|
286
|
-
"Circuit: {} qubits and {} clbits."
|
287
|
-
gate.num_qubits, gate.num_clbits, circuit.num_qubits, circuit.num_clbits
|
288
|
-
)
|
285
|
+
f"of different shapes. Gate: {gate.num_qubits} qubits and {gate.num_clbits} clbits. "
|
286
|
+
f"Circuit: {circuit.num_qubits} qubits and {circuit.num_clbits} clbits."
|
289
287
|
)
|
290
288
|
|
291
289
|
|
qiskit/circuit/gate.py
CHANGED
@@ -104,10 +104,9 @@ class Gate(Instruction):
|
|
104
104
|
num_ctrl_qubits: int = 1,
|
105
105
|
label: str | None = None,
|
106
106
|
ctrl_state: int | str | None = None,
|
107
|
-
annotated: bool =
|
107
|
+
annotated: bool | None = None,
|
108
108
|
):
|
109
|
-
"""
|
110
|
-
Return the controlled version of itself.
|
109
|
+
"""Return the controlled version of itself.
|
111
110
|
|
112
111
|
Implemented either as a controlled gate (ref. :class:`.ControlledGate`)
|
113
112
|
or as an annotated operation (ref. :class:`.AnnotatedOperation`).
|
@@ -118,8 +117,12 @@ class Gate(Instruction):
|
|
118
117
|
operation.
|
119
118
|
ctrl_state: the control state in decimal or as a bitstring
|
120
119
|
(e.g. ``'111'``). If ``None``, use ``2**num_ctrl_qubits-1``.
|
121
|
-
annotated: indicates whether the controlled gate
|
122
|
-
as an annotated gate.
|
120
|
+
annotated: indicates whether the controlled gate is implemented
|
121
|
+
as an annotated gate. If ``None``, this is set to ``False``
|
122
|
+
if the controlled gate can directly be constructed, and otherwise
|
123
|
+
set to ``True``. This allows defering the construction process in case the
|
124
|
+
synthesis of the controlled gate requires more information (e.g.
|
125
|
+
values of unbound parameters).
|
123
126
|
|
124
127
|
Returns:
|
125
128
|
Controlled version of the given operation.
|
@@ -127,7 +130,7 @@ class Gate(Instruction):
|
|
127
130
|
Raises:
|
128
131
|
QiskitError: unrecognized mode or invalid ctrl_state
|
129
132
|
"""
|
130
|
-
if not annotated:
|
133
|
+
if not annotated: # captures both None and False
|
131
134
|
# pylint: disable=cyclic-import
|
132
135
|
from .add_control import add_control
|
133
136
|
|
@@ -177,7 +180,7 @@ class Gate(Instruction):
|
|
177
180
|
for arg in zip(*qargs):
|
178
181
|
yield list(arg), []
|
179
182
|
else:
|
180
|
-
raise CircuitError("Not sure how to combine these qubit arguments:\n
|
183
|
+
raise CircuitError(f"Not sure how to combine these qubit arguments:\n {qargs}\n")
|
181
184
|
|
182
185
|
def broadcast_arguments(self, qargs: list, cargs: list) -> Iterable[tuple[list, list]]:
|
183
186
|
"""Validation and handling of the arguments and its relationship.
|
@@ -236,7 +239,7 @@ class Gate(Instruction):
|
|
236
239
|
elif len(qargs) >= 3:
|
237
240
|
return Gate._broadcast_3_or_more_args(qargs)
|
238
241
|
else:
|
239
|
-
raise CircuitError("This gate cannot handle
|
242
|
+
raise CircuitError(f"This gate cannot handle {len(qargs)} arguments")
|
240
243
|
|
241
244
|
def validate_parameter(self, parameter):
|
242
245
|
"""Gate parameters should be int, float, or ParameterExpression"""
|
qiskit/circuit/instruction.py
CHANGED
@@ -34,6 +34,7 @@ The circuit itself keeps this context.
|
|
34
34
|
from __future__ import annotations
|
35
35
|
|
36
36
|
import copy
|
37
|
+
import warnings
|
37
38
|
from itertools import zip_longest
|
38
39
|
import math
|
39
40
|
from typing import List, Type
|
@@ -47,7 +48,7 @@ from qiskit.circuit.parameter import ParameterExpression
|
|
47
48
|
from qiskit.circuit.operation import Operation
|
48
49
|
|
49
50
|
from qiskit.circuit.annotated_operation import AnnotatedOperation, InverseModifier
|
50
|
-
|
51
|
+
from qiskit.utils import deprecate_func
|
51
52
|
|
52
53
|
_CUTOFF_PRECISION = 1e-10
|
53
54
|
|
@@ -58,6 +59,7 @@ class Instruction(Operation):
|
|
58
59
|
# Class attribute to treat like barrier for transpiler, unroller, drawer
|
59
60
|
# NOTE: Using this attribute may change in the future (See issue # 5811)
|
60
61
|
_directive = False
|
62
|
+
_standard_gate = None
|
61
63
|
|
62
64
|
def __init__(self, name, num_qubits, num_clbits, params, duration=None, unit="dt", label=None):
|
63
65
|
"""Create a new instruction.
|
@@ -80,7 +82,7 @@ class Instruction(Operation):
|
|
80
82
|
raise CircuitError("num_qubits and num_clbits must be integer.")
|
81
83
|
if num_qubits < 0 or num_clbits < 0:
|
82
84
|
raise CircuitError(
|
83
|
-
"bad instruction dimensions:
|
85
|
+
f"bad instruction dimensions: {num_qubits} qubits, {num_clbits} clbits."
|
84
86
|
)
|
85
87
|
self._name = name
|
86
88
|
self._num_qubits = num_qubits
|
@@ -114,12 +116,12 @@ class Instruction(Operation):
|
|
114
116
|
The "base class" of an instruction is the lowest class in its inheritance tree that the
|
115
117
|
object should be considered entirely compatible with for _all_ circuit applications. This
|
116
118
|
typically means that the subclass is defined purely to offer some sort of programmer
|
117
|
-
convenience over the base class, and the base class is the "true" class for a
|
119
|
+
convenience over the base class, and the base class is the "true" class for a behavioral
|
118
120
|
perspective. In particular, you should *not* override :attr:`base_class` if you are
|
119
121
|
defining a custom version of an instruction that will be implemented differently by
|
120
|
-
hardware, such as an alternative measurement strategy, or a version of a
|
122
|
+
hardware, such as an alternative measurement strategy, or a version of a parametrized gate
|
121
123
|
with a particular set of parameters for the purposes of distinguishing it in a
|
122
|
-
:class:`.Target` from the full
|
124
|
+
:class:`.Target` from the full parametrized gate.
|
123
125
|
|
124
126
|
This is often exactly equivalent to ``type(obj)``, except in the case of singleton instances
|
125
127
|
of standard-library instructions. These singleton instances are special subclasses of their
|
@@ -187,11 +189,12 @@ class Instruction(Operation):
|
|
187
189
|
return False
|
188
190
|
|
189
191
|
for self_param, other_param in zip_longest(self.params, other.params):
|
190
|
-
|
192
|
+
if isinstance(self_param, numpy.ndarray):
|
193
|
+
if numpy.array_equal(self_param, other_param):
|
194
|
+
continue
|
195
|
+
else:
|
191
196
|
if self_param == other_param:
|
192
197
|
continue
|
193
|
-
except ValueError:
|
194
|
-
pass
|
195
198
|
|
196
199
|
try:
|
197
200
|
self_asarray = numpy.asarray(self_param)
|
@@ -221,8 +224,9 @@ class Instruction(Operation):
|
|
221
224
|
str: A representation of the Instruction instance with the name,
|
222
225
|
number of qubits, classical bits and params( if any )
|
223
226
|
"""
|
224
|
-
return
|
225
|
-
self.name, self.num_qubits,
|
227
|
+
return (
|
228
|
+
f"Instruction(name='{self.name}', num_qubits={self.num_qubits}, "
|
229
|
+
f"num_clbits={self.num_clbits}, params={self.params})"
|
226
230
|
)
|
227
231
|
|
228
232
|
def soft_compare(self, other: "Instruction") -> bool:
|
@@ -298,7 +302,7 @@ class Instruction(Operation):
|
|
298
302
|
"""Return whether the :class:`Instruction` contains :ref:`compile-time parameters
|
299
303
|
<circuit-compile-time-parameters>`."""
|
300
304
|
return any(
|
301
|
-
isinstance(param, ParameterExpression) and param.parameters for param in self.
|
305
|
+
isinstance(param, ParameterExpression) and param.parameters for param in self._params
|
302
306
|
)
|
303
307
|
|
304
308
|
@property
|
@@ -356,9 +360,23 @@ class Instruction(Operation):
|
|
356
360
|
"""Set the time unit of duration."""
|
357
361
|
self._unit = unit
|
358
362
|
|
363
|
+
@deprecate_func(
|
364
|
+
since="1.2",
|
365
|
+
removal_timeline="in the 2.0 release",
|
366
|
+
additional_msg="The `Qobj` class and related functionality are part of the deprecated "
|
367
|
+
"`BackendV1` workflow, and no longer necessary for `BackendV2`. If a user "
|
368
|
+
"workflow requires `Qobj` it likely relies on deprecated functionality and "
|
369
|
+
"should be updated to use `BackendV2`.",
|
370
|
+
)
|
359
371
|
def assemble(self):
|
360
372
|
"""Assemble a QasmQobjInstruction"""
|
361
|
-
|
373
|
+
return self._assemble()
|
374
|
+
|
375
|
+
def _assemble(self):
|
376
|
+
with warnings.catch_warnings():
|
377
|
+
# The class QasmQobjInstruction is deprecated
|
378
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning, module="qiskit")
|
379
|
+
instruction = QasmQobjInstruction(name=self.name)
|
362
380
|
# Evaluate parameters
|
363
381
|
if self.params:
|
364
382
|
params = [x.evalf(x) if hasattr(x, "evalf") else x for x in self.params]
|
@@ -455,7 +473,7 @@ class Instruction(Operation):
|
|
455
473
|
return AnnotatedOperation(self, InverseModifier())
|
456
474
|
|
457
475
|
if self.definition is None:
|
458
|
-
raise CircuitError("inverse() not implemented for
|
476
|
+
raise CircuitError(f"inverse() not implemented for {self.name}.")
|
459
477
|
|
460
478
|
from qiskit.circuit import Gate # pylint: disable=cyclic-import
|
461
479
|
|
qiskit/circuit/instructionset.py
CHANGED
@@ -140,13 +140,10 @@ class InstructionSet:
|
|
140
140
|
)
|
141
141
|
if self._requester is not None:
|
142
142
|
classical = self._requester(classical)
|
143
|
-
for instruction in self._instructions:
|
143
|
+
for idx, instruction in enumerate(self._instructions):
|
144
144
|
if isinstance(instruction, CircuitInstruction):
|
145
145
|
updated = instruction.operation.c_if(classical, val)
|
146
|
-
|
147
|
-
raise CircuitError(
|
148
|
-
"SingletonGate instances can only be added to InstructionSet via _add_ref"
|
149
|
-
)
|
146
|
+
self._instructions[idx] = instruction.replace(operation=updated)
|
150
147
|
else:
|
151
148
|
data, idx = instruction
|
152
149
|
instruction = data[idx]
|
@@ -226,6 +226,7 @@ the computational basis and the Fourier basis.
|
|
226
226
|
:template: autosummary/class_no_inherited_members.rst
|
227
227
|
|
228
228
|
QFT
|
229
|
+
QFTGate
|
229
230
|
|
230
231
|
Arithmetic Circuits
|
231
232
|
===================
|
@@ -523,7 +524,7 @@ from .boolean_logic import (
|
|
523
524
|
XOR,
|
524
525
|
InnerProduct,
|
525
526
|
)
|
526
|
-
from .basis_change import QFT
|
527
|
+
from .basis_change import QFT, QFTGate
|
527
528
|
from .arithmetic import (
|
528
529
|
FunctionalPauliRotations,
|
529
530
|
LinearPauliRotations,
|
@@ -153,7 +153,7 @@ class LinearPauliRotations(FunctionalPauliRotations):
|
|
153
153
|
if raise_on_failure:
|
154
154
|
raise CircuitError(
|
155
155
|
"Not enough qubits in the circuit, need at least "
|
156
|
-
"{
|
156
|
+
f"{self.num_state_qubits + 1}."
|
157
157
|
)
|
158
158
|
|
159
159
|
return valid
|
@@ -122,7 +122,7 @@ class PiecewiseChebyshev(BlueprintCircuit):
|
|
122
122
|
if raise_on_failure:
|
123
123
|
raise CircuitError(
|
124
124
|
"Not enough qubits in the circuit, need at least "
|
125
|
-
"{
|
125
|
+
f"{self.num_state_qubits + 1}."
|
126
126
|
)
|
127
127
|
|
128
128
|
return valid
|