qiskit 1.1.2__cp38-abi3-macosx_10_9_universal2.whl → 1.2.0rc1__cp38-abi3-macosx_10_9_universal2.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.abi3.so +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 +1 -1
- 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 +392 -384
- 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 +41 -127
- 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 +32 -24
- qiskit/providers/fake_provider/fake_backend.py +10 -3
- qiskit/providers/fake_provider/fake_openpulse_2q.py +154 -146
- qiskit/providers/fake_provider/fake_openpulse_3q.py +226 -217
- qiskit/providers/fake_provider/fake_qasm_backend.py +5 -1
- qiskit/providers/fake_provider/generic_backend_v2.py +80 -50
- qiskit/providers/models/__init__.py +11 -0
- 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 +578 -481
- 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/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 +14 -16
- 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 +82 -63
- 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 +11 -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 +1 -1
- 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 +11 -11
- 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 +117 -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 +19 -67
- 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 +5 -12
- 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.0rc1.dist-info}/METADATA +26 -26
- {qiskit-1.1.2.dist-info → qiskit-1.2.0rc1.dist-info}/RECORD +340 -338
- {qiskit-1.1.2.dist-info → qiskit-1.2.0rc1.dist-info}/WHEEL +1 -1
- {qiskit-1.1.2.dist-info → qiskit-1.2.0rc1.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.0rc1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.1.2.dist-info → qiskit-1.2.0rc1.dist-info}/top_level.txt +0 -0
@@ -45,8 +45,6 @@ class QuantumCircuitData(MutableSequence):
|
|
45
45
|
operation, qargs, cargs = value
|
46
46
|
value = self._resolve_legacy_value(operation, qargs, cargs)
|
47
47
|
self._circuit._data[key] = value
|
48
|
-
if isinstance(value.operation, Instruction):
|
49
|
-
self._circuit._update_parameter_table(value.operation)
|
50
48
|
|
51
49
|
def _resolve_legacy_value(self, operation, qargs, cargs) -> CircuitInstruction:
|
52
50
|
"""Resolve the old-style 3-tuple into the new :class:`CircuitInstruction` type."""
|
@@ -55,8 +53,8 @@ class QuantumCircuitData(MutableSequence):
|
|
55
53
|
if not isinstance(operation, Operation):
|
56
54
|
raise CircuitError("object is not an Operation.")
|
57
55
|
|
58
|
-
expanded_qargs = [self._circuit.
|
59
|
-
expanded_cargs = [self._circuit.
|
56
|
+
expanded_qargs = [self._circuit._qbit_argument_conversion(qarg) for qarg in qargs or []]
|
57
|
+
expanded_cargs = [self._circuit._cbit_argument_conversion(carg) for carg in cargs or []]
|
60
58
|
|
61
59
|
if isinstance(operation, Instruction):
|
62
60
|
broadcast_args = list(operation.broadcast_arguments(expanded_qargs, expanded_cargs))
|
@@ -76,7 +74,7 @@ class QuantumCircuitData(MutableSequence):
|
|
76
74
|
return CircuitInstruction(operation, tuple(qargs), tuple(cargs))
|
77
75
|
|
78
76
|
def insert(self, index, value):
|
79
|
-
self._circuit._data.insert(index,
|
77
|
+
self._circuit._data.insert(index, value.replace(qubits=(), clbits=()))
|
80
78
|
try:
|
81
79
|
self[index] = value
|
82
80
|
except CircuitError:
|
qiskit/circuit/random/utils.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# This code is part of Qiskit.
|
2
2
|
#
|
3
|
-
# (C) Copyright IBM 2017.
|
3
|
+
# (C) Copyright IBM 2017, 2024.
|
4
4
|
#
|
5
5
|
# This code is licensed under the Apache License, Version 2.0. You may
|
6
6
|
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
@@ -18,10 +18,18 @@ from qiskit.circuit import ClassicalRegister, QuantumCircuit, CircuitInstruction
|
|
18
18
|
from qiskit.circuit import Reset
|
19
19
|
from qiskit.circuit.library import standard_gates
|
20
20
|
from qiskit.circuit.exceptions import CircuitError
|
21
|
+
from qiskit.quantum_info.operators.symplectic.clifford_circuits import _BASIS_1Q, _BASIS_2Q
|
21
22
|
|
22
23
|
|
23
24
|
def random_circuit(
|
24
|
-
num_qubits,
|
25
|
+
num_qubits,
|
26
|
+
depth,
|
27
|
+
max_operands=4,
|
28
|
+
measure=False,
|
29
|
+
conditional=False,
|
30
|
+
reset=False,
|
31
|
+
seed=None,
|
32
|
+
num_operand_distribution: dict = None,
|
25
33
|
):
|
26
34
|
"""Generate random circuit of arbitrary size and form.
|
27
35
|
|
@@ -44,6 +52,10 @@ def random_circuit(
|
|
44
52
|
conditional (bool): if True, insert middle measurements and conditionals
|
45
53
|
reset (bool): if True, insert middle resets
|
46
54
|
seed (int): sets random seed (optional)
|
55
|
+
num_operand_distribution (dict): a distribution of gates that specifies the ratio
|
56
|
+
of 1-qubit, 2-qubit, 3-qubit, ..., n-qubit gates in the random circuit. Expect a
|
57
|
+
deviation from the specified ratios that depends on the size of the requested
|
58
|
+
random circuit. (optional)
|
47
59
|
|
48
60
|
Returns:
|
49
61
|
QuantumCircuit: constructed circuit
|
@@ -51,11 +63,38 @@ def random_circuit(
|
|
51
63
|
Raises:
|
52
64
|
CircuitError: when invalid options given
|
53
65
|
"""
|
66
|
+
if seed is None:
|
67
|
+
seed = np.random.randint(0, np.iinfo(np.int32).max)
|
68
|
+
rng = np.random.default_rng(seed)
|
69
|
+
|
70
|
+
if num_operand_distribution:
|
71
|
+
if min(num_operand_distribution.keys()) < 1 or max(num_operand_distribution.keys()) > 4:
|
72
|
+
raise CircuitError("'num_operand_distribution' must have keys between 1 and 4")
|
73
|
+
for key, prob in num_operand_distribution.items():
|
74
|
+
if key > num_qubits and prob != 0.0:
|
75
|
+
raise CircuitError(
|
76
|
+
f"'num_operand_distribution' cannot have {key}-qubit gates"
|
77
|
+
f" for circuit with {num_qubits} qubits"
|
78
|
+
)
|
79
|
+
num_operand_distribution = dict(sorted(num_operand_distribution.items()))
|
80
|
+
|
81
|
+
if not num_operand_distribution and max_operands:
|
82
|
+
if max_operands < 1 or max_operands > 4:
|
83
|
+
raise CircuitError("max_operands must be between 1 and 4")
|
84
|
+
max_operands = max_operands if num_qubits > max_operands else num_qubits
|
85
|
+
rand_dist = rng.dirichlet(
|
86
|
+
np.ones(max_operands)
|
87
|
+
) # This will create a random distribution that sums to 1
|
88
|
+
num_operand_distribution = {i + 1: rand_dist[i] for i in range(max_operands)}
|
89
|
+
num_operand_distribution = dict(sorted(num_operand_distribution.items()))
|
90
|
+
|
91
|
+
# Here we will use np.isclose() because very rarely there might be floating
|
92
|
+
# point precision errors
|
93
|
+
if not np.isclose(sum(num_operand_distribution.values()), 1):
|
94
|
+
raise CircuitError("The sum of all the values in 'num_operand_distribution' is not 1.")
|
95
|
+
|
54
96
|
if num_qubits == 0:
|
55
97
|
return QuantumCircuit()
|
56
|
-
if max_operands < 1 or max_operands > 4:
|
57
|
-
raise CircuitError("max_operands must be between 1 and 4")
|
58
|
-
max_operands = max_operands if num_qubits > max_operands else num_qubits
|
59
98
|
|
60
99
|
gates_1q = [
|
61
100
|
# (Gate class, number of qubits, number of parameters)
|
@@ -119,17 +158,26 @@ def random_circuit(
|
|
119
158
|
(standard_gates.RC3XGate, 4, 0),
|
120
159
|
]
|
121
160
|
|
122
|
-
|
123
|
-
|
124
|
-
gates.extend(gates_2q)
|
125
|
-
if max_operands >= 3:
|
126
|
-
gates.extend(gates_3q)
|
127
|
-
if max_operands >= 4:
|
128
|
-
gates.extend(gates_4q)
|
129
|
-
gates = np.array(
|
130
|
-
gates, dtype=[("class", object), ("num_qubits", np.int64), ("num_params", np.int64)]
|
161
|
+
gates_1q = np.array(
|
162
|
+
gates_1q, dtype=[("class", object), ("num_qubits", np.int64), ("num_params", np.int64)]
|
131
163
|
)
|
132
|
-
|
164
|
+
gates_2q = np.array(gates_2q, dtype=gates_1q.dtype)
|
165
|
+
gates_3q = np.array(gates_3q, dtype=gates_1q.dtype)
|
166
|
+
gates_4q = np.array(gates_4q, dtype=gates_1q.dtype)
|
167
|
+
|
168
|
+
all_gate_lists = [gates_1q, gates_2q, gates_3q, gates_4q]
|
169
|
+
|
170
|
+
# Here we will create a list 'gates_to_consider' that will have a
|
171
|
+
# subset of different n-qubit gates and will also create a list for
|
172
|
+
# ratio (or probability) for each gates
|
173
|
+
gates_to_consider = []
|
174
|
+
distribution = []
|
175
|
+
for n_qubits, ratio in num_operand_distribution.items():
|
176
|
+
gate_list = all_gate_lists[n_qubits - 1]
|
177
|
+
gates_to_consider.extend(gate_list)
|
178
|
+
distribution.extend([ratio / len(gate_list)] * len(gate_list))
|
179
|
+
|
180
|
+
gates = np.array(gates_to_consider, dtype=gates_1q.dtype)
|
133
181
|
|
134
182
|
qc = QuantumCircuit(num_qubits)
|
135
183
|
|
@@ -137,33 +185,65 @@ def random_circuit(
|
|
137
185
|
cr = ClassicalRegister(num_qubits, "c")
|
138
186
|
qc.add_register(cr)
|
139
187
|
|
140
|
-
if seed is None:
|
141
|
-
seed = np.random.randint(0, np.iinfo(np.int32).max)
|
142
|
-
rng = np.random.default_rng(seed)
|
143
|
-
|
144
188
|
qubits = np.array(qc.qubits, dtype=object, copy=True)
|
145
189
|
|
190
|
+
# Counter to keep track of number of different gate types
|
191
|
+
counter = np.zeros(len(all_gate_lists) + 1, dtype=np.int64)
|
192
|
+
total_gates = 0
|
193
|
+
|
146
194
|
# Apply arbitrary random operations in layers across all qubits.
|
147
195
|
for layer_number in range(depth):
|
148
196
|
# We generate all the randomness for the layer in one go, to avoid many separate calls to
|
149
|
-
# the
|
197
|
+
# the randomization routines, which can be fairly slow.
|
150
198
|
|
151
199
|
# This reliably draws too much randomness, but it's less expensive than looping over more
|
152
200
|
# calls to the rng. After, trim it down by finding the point when we've used all the qubits.
|
153
|
-
|
201
|
+
|
202
|
+
# Due to the stochastic nature of generating a random circuit, the resulting ratios
|
203
|
+
# may not precisely match the specified values from `num_operand_distribution`. Expect
|
204
|
+
# greater deviations from the target ratios in quantum circuits with fewer qubits and
|
205
|
+
# shallower depths, and smaller deviations in larger and deeper quantum circuits.
|
206
|
+
# For more information on how the distribution changes with number of qubits and depth
|
207
|
+
# refer to the pull request #12483 on Qiskit GitHub.
|
208
|
+
|
209
|
+
gate_specs = rng.choice(gates, size=len(qubits), p=distribution)
|
154
210
|
cumulative_qubits = np.cumsum(gate_specs["num_qubits"], dtype=np.int64)
|
211
|
+
|
155
212
|
# Efficiently find the point in the list where the total gates would use as many as
|
156
213
|
# possible of, but not more than, the number of qubits in the layer. If there's slack, fill
|
157
214
|
# it with 1q gates.
|
158
215
|
max_index = np.searchsorted(cumulative_qubits, num_qubits, side="right")
|
159
216
|
gate_specs = gate_specs[:max_index]
|
217
|
+
|
160
218
|
slack = num_qubits - cumulative_qubits[max_index - 1]
|
161
|
-
if slack:
|
162
|
-
gate_specs = np.hstack((gate_specs, rng.choice(gates_1q, size=slack)))
|
163
219
|
|
164
|
-
#
|
220
|
+
# Updating the counter for 1-qubit, 2-qubit, 3-qubit and 4-qubit gates
|
221
|
+
gate_qubits = gate_specs["num_qubits"]
|
222
|
+
counter += np.bincount(gate_qubits, minlength=len(all_gate_lists) + 1)
|
223
|
+
|
224
|
+
total_gates += len(gate_specs)
|
225
|
+
|
226
|
+
# Slack handling loop, this loop will add gates to fill
|
227
|
+
# the slack while respecting the 'num_operand_distribution'
|
228
|
+
while slack > 0:
|
229
|
+
gate_added_flag = False
|
230
|
+
|
231
|
+
for key, dist in sorted(num_operand_distribution.items(), reverse=True):
|
232
|
+
if slack >= key and counter[key] / total_gates < dist:
|
233
|
+
gate_to_add = np.array(
|
234
|
+
all_gate_lists[key - 1][rng.integers(0, len(all_gate_lists[key - 1]))]
|
235
|
+
)
|
236
|
+
gate_specs = np.hstack((gate_specs, gate_to_add))
|
237
|
+
counter[key] += 1
|
238
|
+
total_gates += 1
|
239
|
+
slack -= key
|
240
|
+
gate_added_flag = True
|
241
|
+
if not gate_added_flag:
|
242
|
+
break
|
243
|
+
|
244
|
+
# For efficiency in the Python loop, this uses Numpy vectorization to pre-calculate the
|
165
245
|
# indices into the lists of qubits and parameters for every gate, and then suitably
|
166
|
-
#
|
246
|
+
# randomizes those lists.
|
167
247
|
q_indices = np.empty(len(gate_specs) + 1, dtype=np.int64)
|
168
248
|
p_indices = np.empty(len(gate_specs) + 1, dtype=np.int64)
|
169
249
|
q_indices[0] = p_indices[0] = 0
|
@@ -202,8 +282,77 @@ def random_circuit(
|
|
202
282
|
):
|
203
283
|
operation = gate(*parameters[p_start:p_end])
|
204
284
|
qc._append(CircuitInstruction(operation=operation, qubits=qubits[q_start:q_end]))
|
205
|
-
|
206
285
|
if measure:
|
207
286
|
qc.measure(qc.qubits, cr)
|
208
287
|
|
209
288
|
return qc
|
289
|
+
|
290
|
+
|
291
|
+
def random_clifford_circuit(num_qubits, num_gates, gates="all", seed=None):
|
292
|
+
"""Generate a pseudo-random Clifford circuit.
|
293
|
+
|
294
|
+
This function will generate a Clifford circuit by randomly selecting the chosen amount of Clifford
|
295
|
+
gates from the set of standard gates in :mod:`qiskit.circuit.library.standard_gates`. For example:
|
296
|
+
|
297
|
+
.. plot::
|
298
|
+
:include-source:
|
299
|
+
|
300
|
+
from qiskit.circuit.random import random_clifford_circuit
|
301
|
+
|
302
|
+
circ = random_clifford_circuit(num_qubits=2, num_gates=6)
|
303
|
+
circ.draw(output='mpl')
|
304
|
+
|
305
|
+
Args:
|
306
|
+
num_qubits (int): number of quantum wires.
|
307
|
+
num_gates (int): number of gates in the circuit.
|
308
|
+
gates (list[str]): optional list of Clifford gate names to randomly sample from.
|
309
|
+
If ``"all"`` (default), use all Clifford gates in the standard library.
|
310
|
+
seed (int | np.random.Generator): sets random seed/generator (optional).
|
311
|
+
|
312
|
+
Returns:
|
313
|
+
QuantumCircuit: constructed circuit
|
314
|
+
"""
|
315
|
+
|
316
|
+
gates_1q = list(set(_BASIS_1Q.keys()) - {"v", "w", "id", "iden", "sinv"})
|
317
|
+
gates_2q = list(_BASIS_2Q.keys())
|
318
|
+
|
319
|
+
if gates == "all":
|
320
|
+
if num_qubits == 1:
|
321
|
+
gates = gates_1q
|
322
|
+
else:
|
323
|
+
gates = gates_1q + gates_2q
|
324
|
+
|
325
|
+
instructions = {
|
326
|
+
"i": (standard_gates.IGate(), 1),
|
327
|
+
"x": (standard_gates.XGate(), 1),
|
328
|
+
"y": (standard_gates.YGate(), 1),
|
329
|
+
"z": (standard_gates.ZGate(), 1),
|
330
|
+
"h": (standard_gates.HGate(), 1),
|
331
|
+
"s": (standard_gates.SGate(), 1),
|
332
|
+
"sdg": (standard_gates.SdgGate(), 1),
|
333
|
+
"sx": (standard_gates.SXGate(), 1),
|
334
|
+
"sxdg": (standard_gates.SXdgGate(), 1),
|
335
|
+
"cx": (standard_gates.CXGate(), 2),
|
336
|
+
"cy": (standard_gates.CYGate(), 2),
|
337
|
+
"cz": (standard_gates.CZGate(), 2),
|
338
|
+
"swap": (standard_gates.SwapGate(), 2),
|
339
|
+
"iswap": (standard_gates.iSwapGate(), 2),
|
340
|
+
"ecr": (standard_gates.ECRGate(), 2),
|
341
|
+
"dcx": (standard_gates.DCXGate(), 2),
|
342
|
+
}
|
343
|
+
|
344
|
+
if isinstance(seed, np.random.Generator):
|
345
|
+
rng = seed
|
346
|
+
else:
|
347
|
+
rng = np.random.default_rng(seed)
|
348
|
+
|
349
|
+
samples = rng.choice(gates, num_gates)
|
350
|
+
|
351
|
+
circ = QuantumCircuit(num_qubits)
|
352
|
+
|
353
|
+
for name in samples:
|
354
|
+
gate, nqargs = instructions[name]
|
355
|
+
qargs = rng.choice(range(num_qubits), nqargs, replace=False).tolist()
|
356
|
+
circ.append(gate, qargs, copy=False)
|
357
|
+
|
358
|
+
return circ
|
qiskit/circuit/register.py
CHANGED
@@ -67,7 +67,7 @@ class Register:
|
|
67
67
|
if (size, bits) == (None, None) or (size is not None and bits is not None):
|
68
68
|
raise CircuitError(
|
69
69
|
"Exactly one of the size or bits arguments can be "
|
70
|
-
"provided. Provided size
|
70
|
+
f"provided. Provided size={size} bits={bits}."
|
71
71
|
)
|
72
72
|
|
73
73
|
# validate (or cast) size
|
@@ -81,20 +81,18 @@ class Register:
|
|
81
81
|
|
82
82
|
if not valid_size:
|
83
83
|
raise CircuitError(
|
84
|
-
"Register size must be an integer. (
|
85
|
-
% (type(size).__name__, size)
|
84
|
+
f"Register size must be an integer. ({type(size).__name__} '{size}' was provided)"
|
86
85
|
)
|
87
86
|
size = int(size) # cast to int
|
88
87
|
|
89
88
|
if size < 0:
|
90
89
|
raise CircuitError(
|
91
|
-
"Register size must be non-negative (
|
92
|
-
% (type(size).__name__, size)
|
90
|
+
f"Register size must be non-negative ({type(size).__name__} '{size}' was provided)"
|
93
91
|
)
|
94
92
|
|
95
93
|
# validate (or cast) name
|
96
94
|
if name is None:
|
97
|
-
name = "
|
95
|
+
name = f"{self.prefix}{next(self.instances_counter)}"
|
98
96
|
else:
|
99
97
|
try:
|
100
98
|
name = str(name)
|
@@ -108,7 +106,7 @@ class Register:
|
|
108
106
|
self._size = size
|
109
107
|
|
110
108
|
self._hash = hash((type(self), self._name, self._size))
|
111
|
-
self._repr = "
|
109
|
+
self._repr = f"{self.__class__.__qualname__}({self.size}, '{self.name}')"
|
112
110
|
if bits is not None:
|
113
111
|
# check duplicated bits
|
114
112
|
if self._size != len(set(bits)):
|
qiskit/circuit/singleton.py
CHANGED
@@ -42,7 +42,7 @@ The same can be true for, for example, :class:`.Measure`, except that it's a sub
|
|
42
42
|
heart of Qiskit's data model for circuits.
|
43
43
|
|
44
44
|
From a library-author perspective, the minimum that is needed to enhance a :class:`.Gate` or
|
45
|
-
:class:`~.circuit.Instruction` with this
|
45
|
+
:class:`~.circuit.Instruction` with this behavior is to inherit from :class:`SingletonGate`
|
46
46
|
(:class:`SingletonInstruction`) instead of :class:`.Gate` (:class:`~.circuit.Instruction`), and for
|
47
47
|
the ``__init__`` method to have defaults for all of its arguments (these will be the state of the
|
48
48
|
singleton instance). For example::
|
@@ -175,7 +175,7 @@ Implementation
|
|
175
175
|
This section is primarily developer documentation for the code; none of the machinery described
|
176
176
|
here is public, and it is not safe to inherit from any of it directly.
|
177
177
|
|
178
|
-
There are several moving parts to tackle here. The
|
178
|
+
There are several moving parts to tackle here. The behavior of having ``XGate()`` return some
|
179
179
|
singleton object that is an (inexact) instance of :class:`.XGate` but *without* calling ``__init__``
|
180
180
|
requires us to override :class:`type.__call__ <type>`. This means that :class:`.XGate` must have a
|
181
181
|
metaclass that defines ``__call__`` to return the singleton instance.
|
@@ -484,7 +484,7 @@ class _SingletonInstructionOverrides(Instruction):
|
|
484
484
|
instruction._define()
|
485
485
|
# We use this `list` subclass that rejects all mutation rather than a simple `tuple` because
|
486
486
|
# the `params` typing is specified as `list`. Various places in the library and beyond do
|
487
|
-
# `x.params.copy()` when they want to produce a version they own, which is good
|
487
|
+
# `x.params.copy()` when they want to produce a version they own, which is good behavior,
|
488
488
|
# and would fail if we switched to a `tuple`, which has no `copy` method.
|
489
489
|
instruction._params = _frozenlist(instruction._params)
|
490
490
|
return instruction
|
qiskit/circuit/tools/pi_check.py
CHANGED
@@ -104,9 +104,9 @@ def pi_check(inpt, eps=1e-9, output="text", ndigits=None):
|
|
104
104
|
if power[0].shape[0]:
|
105
105
|
if output == "qasm":
|
106
106
|
if ndigits is None:
|
107
|
-
str_out =
|
107
|
+
str_out = str(single_inpt)
|
108
108
|
else:
|
109
|
-
str_out = "{:.{}g}"
|
109
|
+
str_out = f"{single_inpt:.{ndigits}g}"
|
110
110
|
elif output == "latex":
|
111
111
|
str_out = f"{neg_str}{pi}^{power[0][0] + 2}"
|
112
112
|
elif output == "mpl":
|
@@ -119,9 +119,9 @@ def pi_check(inpt, eps=1e-9, output="text", ndigits=None):
|
|
119
119
|
# multiple or power of pi, since no fractions will exceed MAX_FRAC * pi
|
120
120
|
if abs(single_inpt) >= (MAX_FRAC * np.pi):
|
121
121
|
if ndigits is None:
|
122
|
-
str_out =
|
122
|
+
str_out = str(single_inpt)
|
123
123
|
else:
|
124
|
-
str_out = "{:.{}g}"
|
124
|
+
str_out = f"{single_inpt:.{ndigits}g}"
|
125
125
|
return str_out
|
126
126
|
|
127
127
|
# Fourth check is for fractions for 1*pi in the numer and any
|
qiskit/compiler/assembler.py
CHANGED
@@ -20,7 +20,7 @@ from typing import Dict, List, Optional, Union
|
|
20
20
|
|
21
21
|
import numpy as np
|
22
22
|
|
23
|
-
from qiskit.assembler import
|
23
|
+
from qiskit.assembler import assemble_schedules
|
24
24
|
from qiskit.assembler.run_config import RunConfig
|
25
25
|
from qiskit.circuit import Parameter, QuantumCircuit, Qubit
|
26
26
|
from qiskit.exceptions import QiskitError
|
@@ -29,16 +29,26 @@ from qiskit.pulse import Instruction, LoConfig, Schedule, ScheduleBlock
|
|
29
29
|
from qiskit.pulse.channels import PulseChannel
|
30
30
|
from qiskit.qobj import QasmQobj, PulseQobj, QobjHeader
|
31
31
|
from qiskit.qobj.utils import MeasLevel, MeasReturnType
|
32
|
+
from qiskit.utils import deprecate_func
|
33
|
+
from qiskit.assembler.assemble_circuits import _assemble_circuits
|
32
34
|
|
33
35
|
logger = logging.getLogger(__name__)
|
34
36
|
|
35
37
|
|
36
38
|
def _log_assembly_time(start_time, end_time):
|
37
|
-
log_msg = "Total Assembly Time -
|
39
|
+
log_msg = f"Total Assembly Time - {((end_time - start_time) * 1000):.5f} (ms)"
|
38
40
|
logger.info(log_msg)
|
39
41
|
|
40
42
|
|
41
43
|
# TODO: parallelize over the experiments (serialize each separately, then add global header/config)
|
44
|
+
@deprecate_func(
|
45
|
+
since="1.2",
|
46
|
+
removal_timeline="in the 2.0 release",
|
47
|
+
additional_msg="The `Qobj` class and related functionality are part of the deprecated "
|
48
|
+
"`BackendV1` workflow, and no longer necessary for `BackendV2`. If a user "
|
49
|
+
"workflow requires `Qobj` it likely relies on deprecated functionality and "
|
50
|
+
"should be updated to use `BackendV2`.",
|
51
|
+
)
|
42
52
|
def assemble(
|
43
53
|
experiments: Union[
|
44
54
|
QuantumCircuit,
|
@@ -81,7 +91,7 @@ def assemble(
|
|
81
91
|
to create ``Qobj`` "experiments". It further annotates the experiment payload with
|
82
92
|
header and configurations.
|
83
93
|
|
84
|
-
NOTE: Backend.options is not used within assemble. The required values
|
94
|
+
NOTE: ``Backend.options`` is not used within assemble. The required values
|
85
95
|
(previously given by backend.set_options) should be manually extracted
|
86
96
|
from options and supplied directly when calling.
|
87
97
|
|
@@ -153,27 +163,92 @@ def assemble(
|
|
153
163
|
Raises:
|
154
164
|
QiskitError: if the input cannot be interpreted as either circuits or schedules
|
155
165
|
"""
|
156
|
-
|
157
|
-
|
158
|
-
pulse_qobj = any(isinstance(exp, (ScheduleBlock, Schedule, Instruction)) for exp in experiments)
|
159
|
-
qobj_id, qobj_header, run_config_common_dict = _parse_common_args(
|
166
|
+
return _assemble(
|
167
|
+
experiments,
|
160
168
|
backend,
|
161
169
|
qobj_id,
|
162
170
|
qobj_header,
|
163
171
|
shots,
|
164
172
|
memory,
|
165
173
|
seed_simulator,
|
166
|
-
init_qubits,
|
167
|
-
rep_delay,
|
168
174
|
qubit_lo_freq,
|
169
175
|
meas_lo_freq,
|
170
176
|
qubit_lo_range,
|
171
177
|
meas_lo_range,
|
172
178
|
schedule_los,
|
173
|
-
|
179
|
+
meas_level,
|
180
|
+
meas_return,
|
181
|
+
meas_map,
|
182
|
+
memory_slot_size,
|
183
|
+
rep_time,
|
184
|
+
rep_delay,
|
185
|
+
parameter_binds,
|
186
|
+
parametric_pulses,
|
187
|
+
init_qubits,
|
174
188
|
**run_config,
|
175
189
|
)
|
176
190
|
|
191
|
+
|
192
|
+
def _assemble(
|
193
|
+
experiments: Union[
|
194
|
+
QuantumCircuit,
|
195
|
+
List[QuantumCircuit],
|
196
|
+
Schedule,
|
197
|
+
List[Schedule],
|
198
|
+
ScheduleBlock,
|
199
|
+
List[ScheduleBlock],
|
200
|
+
],
|
201
|
+
backend: Optional[Backend] = None,
|
202
|
+
qobj_id: Optional[str] = None,
|
203
|
+
qobj_header: Optional[Union[QobjHeader, Dict]] = None,
|
204
|
+
shots: Optional[int] = None,
|
205
|
+
memory: Optional[bool] = False,
|
206
|
+
seed_simulator: Optional[int] = None,
|
207
|
+
qubit_lo_freq: Optional[List[float]] = None,
|
208
|
+
meas_lo_freq: Optional[List[float]] = None,
|
209
|
+
qubit_lo_range: Optional[List[float]] = None,
|
210
|
+
meas_lo_range: Optional[List[float]] = None,
|
211
|
+
schedule_los: Optional[
|
212
|
+
Union[
|
213
|
+
List[Union[Dict[PulseChannel, float], LoConfig]],
|
214
|
+
Union[Dict[PulseChannel, float], LoConfig],
|
215
|
+
]
|
216
|
+
] = None,
|
217
|
+
meas_level: Union[int, MeasLevel] = MeasLevel.CLASSIFIED,
|
218
|
+
meas_return: Union[str, MeasReturnType] = MeasReturnType.AVERAGE,
|
219
|
+
meas_map: Optional[List[List[Qubit]]] = None,
|
220
|
+
memory_slot_size: int = 100,
|
221
|
+
rep_time: Optional[int] = None,
|
222
|
+
rep_delay: Optional[float] = None,
|
223
|
+
parameter_binds: Optional[List[Dict[Parameter, float]]] = None,
|
224
|
+
parametric_pulses: Optional[List[str]] = None,
|
225
|
+
init_qubits: bool = True,
|
226
|
+
**run_config: Dict,
|
227
|
+
) -> Union[QasmQobj, PulseQobj]:
|
228
|
+
start_time = time()
|
229
|
+
experiments = experiments if isinstance(experiments, list) else [experiments]
|
230
|
+
pulse_qobj = any(isinstance(exp, (ScheduleBlock, Schedule, Instruction)) for exp in experiments)
|
231
|
+
with warnings.catch_warnings():
|
232
|
+
# The Qobj is deprecated
|
233
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning, module="qiskit")
|
234
|
+
qobj_id, qobj_header, run_config_common_dict = _parse_common_args(
|
235
|
+
backend,
|
236
|
+
qobj_id,
|
237
|
+
qobj_header,
|
238
|
+
shots,
|
239
|
+
memory,
|
240
|
+
seed_simulator,
|
241
|
+
init_qubits,
|
242
|
+
rep_delay,
|
243
|
+
qubit_lo_freq,
|
244
|
+
meas_lo_freq,
|
245
|
+
qubit_lo_range,
|
246
|
+
meas_lo_range,
|
247
|
+
schedule_los,
|
248
|
+
pulse_qobj=pulse_qobj,
|
249
|
+
**run_config,
|
250
|
+
)
|
251
|
+
|
177
252
|
# assemble either circuits or schedules
|
178
253
|
if all(isinstance(exp, QuantumCircuit) for exp in experiments):
|
179
254
|
run_config = _parse_circuit_args(
|
@@ -191,7 +266,7 @@ def assemble(
|
|
191
266
|
)
|
192
267
|
end_time = time()
|
193
268
|
_log_assembly_time(start_time, end_time)
|
194
|
-
return
|
269
|
+
return _assemble_circuits(
|
195
270
|
circuits=bound_experiments,
|
196
271
|
qobj_id=qobj_id,
|
197
272
|
qobj_header=qobj_header,
|
@@ -311,8 +386,8 @@ def _parse_common_args(
|
|
311
386
|
raise QiskitError("Argument 'shots' should be of type 'int'")
|
312
387
|
elif max_shots and max_shots < shots:
|
313
388
|
raise QiskitError(
|
314
|
-
"Number of shots specified:
|
315
|
-
"backend:
|
389
|
+
f"Number of shots specified: {max_shots} exceeds max_shots property of the "
|
390
|
+
f"backend: {max_shots}."
|
316
391
|
)
|
317
392
|
|
318
393
|
dynamic_reprate_enabled = getattr(backend_config, "dynamic_reprate_enabled", False)
|
@@ -397,9 +472,8 @@ def _check_lo_freqs(
|
|
397
472
|
raise QiskitError(f"Each element of {lo_type} LO range must be a 2d list.")
|
398
473
|
if freq < freq_range[0] or freq > freq_range[1]:
|
399
474
|
raise QiskitError(
|
400
|
-
"Qubit {} {} LO frequency is {}.
|
401
|
-
|
402
|
-
)
|
475
|
+
f"Qubit {i} {lo_type} LO frequency is {freq}. "
|
476
|
+
f"The range is [{freq_range[0]}, {freq_range[1]}]."
|
403
477
|
)
|
404
478
|
|
405
479
|
|
@@ -429,9 +503,8 @@ def _parse_pulse_args(
|
|
429
503
|
|
430
504
|
if meas_level not in getattr(backend_config, "meas_levels", [MeasLevel.CLASSIFIED]):
|
431
505
|
raise QiskitError(
|
432
|
-
|
433
|
-
|
434
|
-
)
|
506
|
+
f"meas_level = {meas_level} not supported for backend "
|
507
|
+
f"{backend_config.backend_name}, only {backend_config.meas_levels} is supported"
|
435
508
|
)
|
436
509
|
|
437
510
|
meas_map = meas_map or getattr(backend_config, "meas_map", None)
|
@@ -522,14 +595,12 @@ def _parse_rep_delay(
|
|
522
595
|
if rep_delay_range is not None and isinstance(rep_delay_range, list):
|
523
596
|
if len(rep_delay_range) != 2:
|
524
597
|
raise QiskitError(
|
525
|
-
"Backend rep_delay_range {} must be a list with two entries."
|
526
|
-
rep_delay_range
|
527
|
-
)
|
598
|
+
f"Backend rep_delay_range {rep_delay_range} must be a list with two entries."
|
528
599
|
)
|
529
600
|
if not rep_delay_range[0] <= rep_delay <= rep_delay_range[1]:
|
530
601
|
raise QiskitError(
|
531
|
-
"Supplied rep delay {} not in the supported "
|
532
|
-
"backend range {}"
|
602
|
+
f"Supplied rep delay {rep_delay} not in the supported "
|
603
|
+
f"backend range {rep_delay_range}"
|
533
604
|
)
|
534
605
|
rep_delay = rep_delay * 1e6 # convert sec to μs
|
535
606
|
|
qiskit/compiler/scheduler.py
CHANGED
@@ -23,7 +23,7 @@ from qiskit.circuit.quantumcircuit import QuantumCircuit
|
|
23
23
|
from qiskit.exceptions import QiskitError
|
24
24
|
from qiskit.pulse import InstructionScheduleMap, Schedule
|
25
25
|
from qiskit.providers.backend import Backend
|
26
|
-
from qiskit.scheduler import ScheduleConfig
|
26
|
+
from qiskit.scheduler.config import ScheduleConfig
|
27
27
|
from qiskit.scheduler.schedule_circuit import schedule_circuit
|
28
28
|
from qiskit.utils.parallel import parallel_map
|
29
29
|
|
@@ -31,7 +31,7 @@ logger = logging.getLogger(__name__)
|
|
31
31
|
|
32
32
|
|
33
33
|
def _log_schedule_time(start_time, end_time):
|
34
|
-
log_msg = "Total Scheduling Time -
|
34
|
+
log_msg = f"Total Scheduling Time - {((end_time - start_time) * 1000):.5f} (ms)"
|
35
35
|
logger.info(log_msg)
|
36
36
|
|
37
37
|
|