qiskit 1.0.2__cp38-abi3-win32.whl → 1.1.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 -16
- qiskit/_accelerate.pyd +0 -0
- qiskit/_numpy_compat.py +73 -0
- qiskit/assembler/__init__.py +5 -10
- qiskit/assembler/disassemble.py +5 -6
- qiskit/circuit/__init__.py +1061 -232
- qiskit/circuit/_classical_resource_map.py +10 -6
- qiskit/circuit/_utils.py +18 -8
- qiskit/circuit/annotated_operation.py +21 -0
- qiskit/circuit/barrier.py +10 -13
- qiskit/circuit/bit.py +0 -1
- qiskit/circuit/classical/__init__.py +2 -2
- qiskit/circuit/classical/expr/__init__.py +39 -5
- qiskit/circuit/classical/expr/constructors.py +84 -1
- qiskit/circuit/classical/expr/expr.py +83 -13
- qiskit/circuit/classical/expr/visitors.py +83 -0
- qiskit/circuit/classical/types/__init__.py +5 -4
- qiskit/circuit/classicalfunction/__init__.py +1 -0
- qiskit/circuit/commutation_checker.py +86 -51
- qiskit/circuit/controlflow/_builder_utils.py +9 -1
- qiskit/circuit/controlflow/break_loop.py +8 -22
- qiskit/circuit/controlflow/builder.py +116 -1
- qiskit/circuit/controlflow/continue_loop.py +8 -22
- qiskit/circuit/controlflow/control_flow.py +47 -8
- qiskit/circuit/controlflow/for_loop.py +8 -23
- qiskit/circuit/controlflow/if_else.py +13 -27
- qiskit/circuit/controlflow/switch_case.py +14 -21
- qiskit/circuit/controlflow/while_loop.py +9 -23
- qiskit/circuit/controlledgate.py +2 -2
- qiskit/circuit/delay.py +7 -5
- qiskit/circuit/gate.py +20 -7
- qiskit/circuit/instruction.py +31 -30
- qiskit/circuit/instructionset.py +9 -22
- qiskit/circuit/library/__init__.py +3 -13
- qiskit/circuit/library/arithmetic/integer_comparator.py +2 -2
- qiskit/circuit/library/arithmetic/quadratic_form.py +3 -2
- qiskit/circuit/library/blueprintcircuit.py +29 -7
- qiskit/circuit/library/data_preparation/state_preparation.py +6 -5
- qiskit/circuit/library/generalized_gates/diagonal.py +5 -4
- qiskit/circuit/library/generalized_gates/isometry.py +51 -254
- qiskit/circuit/library/generalized_gates/pauli.py +2 -2
- qiskit/circuit/library/generalized_gates/permutation.py +4 -1
- qiskit/circuit/library/generalized_gates/rv.py +15 -11
- qiskit/circuit/library/generalized_gates/uc.py +2 -98
- qiskit/circuit/library/generalized_gates/unitary.py +9 -4
- qiskit/circuit/library/hamiltonian_gate.py +11 -5
- qiskit/circuit/library/n_local/efficient_su2.py +5 -5
- qiskit/circuit/library/n_local/n_local.py +100 -49
- qiskit/circuit/library/n_local/two_local.py +3 -59
- qiskit/circuit/library/overlap.py +3 -3
- qiskit/circuit/library/phase_oracle.py +1 -1
- qiskit/circuit/library/quantum_volume.py +39 -38
- qiskit/circuit/library/standard_gates/equivalence_library.py +50 -0
- qiskit/circuit/library/standard_gates/global_phase.py +4 -2
- qiskit/circuit/library/standard_gates/i.py +1 -2
- qiskit/circuit/library/standard_gates/iswap.py +1 -2
- qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +11 -5
- qiskit/circuit/library/standard_gates/p.py +31 -15
- qiskit/circuit/library/standard_gates/r.py +4 -3
- qiskit/circuit/library/standard_gates/rx.py +7 -4
- qiskit/circuit/library/standard_gates/rxx.py +4 -3
- qiskit/circuit/library/standard_gates/ry.py +7 -4
- qiskit/circuit/library/standard_gates/ryy.py +4 -3
- qiskit/circuit/library/standard_gates/rz.py +7 -4
- qiskit/circuit/library/standard_gates/rzx.py +4 -3
- qiskit/circuit/library/standard_gates/rzz.py +4 -3
- qiskit/circuit/library/standard_gates/s.py +4 -8
- qiskit/circuit/library/standard_gates/t.py +2 -4
- qiskit/circuit/library/standard_gates/u.py +16 -11
- qiskit/circuit/library/standard_gates/u1.py +6 -2
- qiskit/circuit/library/standard_gates/u2.py +4 -2
- qiskit/circuit/library/standard_gates/u3.py +9 -5
- qiskit/circuit/library/standard_gates/x.py +22 -11
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +4 -3
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +7 -5
- qiskit/circuit/library/standard_gates/z.py +1 -2
- qiskit/circuit/measure.py +4 -1
- qiskit/circuit/operation.py +13 -8
- qiskit/circuit/parameter.py +11 -6
- qiskit/circuit/quantumcircuit.py +1910 -260
- qiskit/circuit/quantumcircuitdata.py +2 -2
- qiskit/circuit/reset.py +5 -2
- qiskit/circuit/store.py +95 -0
- qiskit/compiler/assembler.py +22 -22
- qiskit/compiler/transpiler.py +63 -112
- qiskit/converters/__init__.py +17 -2
- qiskit/converters/circuit_to_dag.py +7 -0
- qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
- qiskit/converters/circuit_to_gate.py +2 -0
- qiskit/converters/circuit_to_instruction.py +22 -0
- qiskit/converters/dag_to_circuit.py +4 -0
- qiskit/converters/dag_to_dagdependency_v2.py +44 -0
- qiskit/dagcircuit/collect_blocks.py +15 -10
- qiskit/dagcircuit/dagcircuit.py +434 -124
- qiskit/dagcircuit/dagdependency.py +19 -12
- qiskit/dagcircuit/dagdependency_v2.py +641 -0
- qiskit/dagcircuit/dagdepnode.py +19 -16
- qiskit/dagcircuit/dagnode.py +14 -4
- qiskit/passmanager/passmanager.py +11 -11
- qiskit/primitives/__init__.py +22 -12
- qiskit/primitives/backend_estimator.py +3 -5
- qiskit/primitives/backend_estimator_v2.py +410 -0
- qiskit/primitives/backend_sampler_v2.py +287 -0
- qiskit/primitives/base/base_estimator.py +4 -9
- qiskit/primitives/base/base_sampler.py +2 -2
- qiskit/primitives/containers/__init__.py +6 -4
- qiskit/primitives/containers/bit_array.py +293 -2
- qiskit/primitives/containers/data_bin.py +123 -50
- qiskit/primitives/containers/estimator_pub.py +10 -3
- qiskit/primitives/containers/observables_array.py +2 -2
- qiskit/primitives/containers/pub_result.py +1 -1
- qiskit/primitives/containers/sampler_pub.py +19 -3
- qiskit/primitives/containers/sampler_pub_result.py +74 -0
- qiskit/primitives/containers/shape.py +4 -4
- qiskit/primitives/statevector_estimator.py +4 -4
- qiskit/primitives/statevector_sampler.py +7 -12
- qiskit/providers/__init__.py +65 -34
- qiskit/providers/backend.py +2 -2
- qiskit/providers/backend_compat.py +8 -10
- qiskit/providers/basic_provider/__init__.py +2 -23
- qiskit/providers/basic_provider/basic_provider_tools.py +67 -31
- qiskit/providers/basic_provider/basic_simulator.py +81 -21
- qiskit/providers/fake_provider/__init__.py +1 -1
- qiskit/providers/fake_provider/fake_1q.py +1 -1
- qiskit/providers/fake_provider/fake_backend.py +3 -408
- qiskit/providers/fake_provider/generic_backend_v2.py +26 -14
- qiskit/providers/models/__init__.py +2 -2
- qiskit/providers/provider.py +16 -0
- qiskit/pulse/builder.py +4 -1
- qiskit/pulse/parameter_manager.py +60 -4
- qiskit/pulse/schedule.py +29 -13
- qiskit/pulse/utils.py +61 -20
- qiskit/qasm2/__init__.py +1 -5
- qiskit/qasm2/parse.py +1 -4
- qiskit/qasm3/__init__.py +42 -5
- qiskit/qasm3/ast.py +19 -0
- qiskit/qasm3/exporter.py +178 -106
- qiskit/qasm3/printer.py +27 -5
- qiskit/qobj/converters/pulse_instruction.py +6 -6
- qiskit/qpy/__init__.py +299 -67
- qiskit/qpy/binary_io/circuits.py +216 -47
- qiskit/qpy/binary_io/schedules.py +42 -36
- qiskit/qpy/binary_io/value.py +201 -22
- qiskit/qpy/common.py +1 -1
- qiskit/qpy/exceptions.py +20 -0
- qiskit/qpy/formats.py +29 -0
- qiskit/qpy/type_keys.py +21 -0
- qiskit/quantum_info/analysis/distance.py +3 -3
- qiskit/quantum_info/analysis/make_observable.py +2 -1
- qiskit/quantum_info/analysis/z2_symmetries.py +2 -1
- qiskit/quantum_info/operators/channel/chi.py +9 -8
- qiskit/quantum_info/operators/channel/choi.py +10 -9
- qiskit/quantum_info/operators/channel/kraus.py +2 -1
- qiskit/quantum_info/operators/channel/ptm.py +10 -9
- qiskit/quantum_info/operators/channel/quantum_channel.py +2 -1
- qiskit/quantum_info/operators/channel/stinespring.py +2 -1
- qiskit/quantum_info/operators/channel/superop.py +12 -11
- qiskit/quantum_info/operators/channel/transformations.py +12 -11
- qiskit/quantum_info/operators/dihedral/dihedral.py +5 -4
- qiskit/quantum_info/operators/operator.py +43 -30
- qiskit/quantum_info/operators/scalar_op.py +10 -9
- qiskit/quantum_info/operators/symplectic/base_pauli.py +70 -59
- qiskit/quantum_info/operators/symplectic/clifford.py +36 -9
- qiskit/quantum_info/operators/symplectic/pauli.py +53 -6
- qiskit/quantum_info/operators/symplectic/pauli_list.py +36 -14
- qiskit/quantum_info/operators/symplectic/random.py +3 -2
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +61 -36
- qiskit/quantum_info/states/densitymatrix.py +13 -13
- qiskit/quantum_info/states/stabilizerstate.py +3 -3
- qiskit/quantum_info/states/statevector.py +14 -13
- qiskit/quantum_info/states/utils.py +5 -3
- qiskit/result/__init__.py +6 -0
- qiskit/result/mitigation/correlated_readout_mitigator.py +3 -2
- qiskit/result/mitigation/local_readout_mitigator.py +2 -1
- qiskit/result/mitigation/utils.py +3 -2
- qiskit/scheduler/__init__.py +10 -1
- qiskit/scheduler/methods/__init__.py +1 -8
- qiskit/synthesis/__init__.py +3 -6
- qiskit/synthesis/discrete_basis/commutator_decompose.py +2 -2
- qiskit/synthesis/evolution/lie_trotter.py +7 -14
- qiskit/synthesis/evolution/qdrift.py +3 -4
- qiskit/synthesis/linear/cnot_synth.py +1 -3
- qiskit/synthesis/linear/linear_circuits_utils.py +1 -1
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +4 -18
- qiskit/synthesis/permutation/__init__.py +1 -0
- qiskit/synthesis/permutation/permutation_reverse_lnn.py +90 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +2 -6
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +165 -954
- qiskit/synthesis/two_qubit/xx_decompose/circuits.py +13 -12
- qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +7 -1
- qiskit/synthesis/unitary/aqc/__init__.py +1 -1
- qiskit/synthesis/unitary/aqc/cnot_structures.py +2 -1
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +2 -1
- qiskit/synthesis/unitary/qsd.py +3 -2
- qiskit/transpiler/__init__.py +7 -3
- qiskit/transpiler/layout.py +140 -61
- qiskit/transpiler/passes/__init__.py +10 -2
- qiskit/transpiler/passes/basis/basis_translator.py +9 -4
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
- qiskit/transpiler/passes/calibration/rzx_builder.py +2 -1
- qiskit/transpiler/passes/layout/apply_layout.py +8 -3
- qiskit/transpiler/passes/layout/sabre_layout.py +15 -3
- qiskit/transpiler/passes/layout/set_layout.py +1 -1
- qiskit/transpiler/passes/optimization/__init__.py +2 -0
- qiskit/transpiler/passes/optimization/commutation_analysis.py +2 -2
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +1 -1
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +1 -1
- qiskit/transpiler/passes/optimization/cx_cancellation.py +10 -0
- qiskit/transpiler/passes/optimization/elide_permutations.py +114 -0
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +9 -3
- qiskit/transpiler/passes/optimization/optimize_annotated.py +248 -12
- qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +1 -3
- qiskit/transpiler/passes/routing/__init__.py +1 -0
- qiskit/transpiler/passes/routing/basic_swap.py +13 -2
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +8 -1
- qiskit/transpiler/passes/routing/lookahead_swap.py +7 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +10 -6
- qiskit/transpiler/passes/routing/star_prerouting.py +417 -0
- qiskit/transpiler/passes/routing/stochastic_swap.py +24 -8
- qiskit/transpiler/passes/scheduling/__init__.py +1 -1
- qiskit/transpiler/passes/scheduling/alap.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/align_measures.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +9 -6
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +8 -0
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +13 -4
- qiskit/transpiler/passes/scheduling/asap.py +1 -2
- qiskit/transpiler/passes/scheduling/base_scheduler.py +21 -2
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +26 -4
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +24 -2
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +28 -4
- qiskit/transpiler/passes/synthesis/aqc_plugin.py +2 -2
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +120 -13
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +162 -55
- qiskit/transpiler/passes/utils/gates_basis.py +3 -3
- qiskit/transpiler/passmanager.py +44 -1
- qiskit/transpiler/preset_passmanagers/__init__.py +3 -3
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +34 -16
- qiskit/transpiler/preset_passmanagers/common.py +4 -6
- qiskit/transpiler/preset_passmanagers/plugin.py +9 -1
- qiskit/utils/__init__.py +3 -2
- qiskit/utils/optionals.py +6 -2
- qiskit/utils/parallel.py +24 -15
- qiskit/visualization/array.py +1 -1
- qiskit/visualization/bloch.py +2 -3
- qiskit/visualization/circuit/matplotlib.py +44 -14
- qiskit/visualization/circuit/text.py +38 -18
- qiskit/visualization/counts_visualization.py +3 -6
- qiskit/visualization/dag_visualization.py +6 -7
- qiskit/visualization/gate_map.py +9 -1
- qiskit/visualization/pulse_v2/interface.py +8 -3
- qiskit/visualization/state_visualization.py +3 -2
- qiskit/visualization/timeline/interface.py +18 -8
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/METADATA +12 -8
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/RECORD +261 -251
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/WHEEL +1 -1
- qiskit/_qasm2.pyd +0 -0
- qiskit/_qasm3.pyd +0 -0
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/entry_points.txt +0 -0
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/top_level.txt +0 -0
@@ -15,14 +15,14 @@ QuantumCircuit.data while maintaining the interface of a python list."""
|
|
15
15
|
|
16
16
|
from collections.abc import MutableSequence
|
17
17
|
|
18
|
-
import qiskit._accelerate.
|
18
|
+
import qiskit._accelerate.circuit
|
19
19
|
|
20
20
|
from .exceptions import CircuitError
|
21
21
|
from .instruction import Instruction
|
22
22
|
from .operation import Operation
|
23
23
|
|
24
24
|
|
25
|
-
CircuitInstruction = qiskit._accelerate.
|
25
|
+
CircuitInstruction = qiskit._accelerate.circuit.CircuitInstruction
|
26
26
|
|
27
27
|
|
28
28
|
class QuantumCircuitData(MutableSequence):
|
qiskit/circuit/reset.py
CHANGED
@@ -18,10 +18,13 @@ from qiskit.circuit.singleton import SingletonInstruction, stdlib_singleton_key
|
|
18
18
|
|
19
19
|
|
20
20
|
class Reset(SingletonInstruction):
|
21
|
-
"""
|
21
|
+
r"""Incoherently reset a qubit to the :math:`\lvert0\rangle` state."""
|
22
22
|
|
23
23
|
def __init__(self, label=None, *, duration=None, unit="dt"):
|
24
|
-
"""
|
24
|
+
"""
|
25
|
+
Args:
|
26
|
+
label: optional string label of this instruction.
|
27
|
+
"""
|
25
28
|
super().__init__("reset", 1, 0, [], label=label, duration=duration, unit=unit)
|
26
29
|
|
27
30
|
_singleton_lookup_key = stdlib_singleton_key()
|
qiskit/circuit/store.py
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2023.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""The 'Store' operation."""
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
import typing
|
18
|
+
|
19
|
+
from .exceptions import CircuitError
|
20
|
+
from .classical import expr, types
|
21
|
+
from .instruction import Instruction
|
22
|
+
|
23
|
+
|
24
|
+
def _handle_equal_types(lvalue: expr.Expr, rvalue: expr.Expr, /) -> tuple[expr.Expr, expr.Expr]:
|
25
|
+
return lvalue, rvalue
|
26
|
+
|
27
|
+
|
28
|
+
def _handle_implicit_cast(lvalue: expr.Expr, rvalue: expr.Expr, /) -> tuple[expr.Expr, expr.Expr]:
|
29
|
+
return lvalue, expr.Cast(rvalue, lvalue.type, implicit=True)
|
30
|
+
|
31
|
+
|
32
|
+
def _requires_lossless_cast(lvalue: expr.Expr, rvalue: expr.Expr, /) -> typing.NoReturn:
|
33
|
+
raise CircuitError(f"an explicit cast is required from '{rvalue.type}' to '{lvalue.type}'")
|
34
|
+
|
35
|
+
|
36
|
+
def _requires_dangerous_cast(lvalue: expr.Expr, rvalue: expr.Expr, /) -> typing.NoReturn:
|
37
|
+
raise CircuitError(
|
38
|
+
f"an explicit cast is required from '{rvalue.type}' to '{lvalue.type}', which may be lossy"
|
39
|
+
)
|
40
|
+
|
41
|
+
|
42
|
+
def _no_cast_possible(lvalue: expr.Expr, rvalue: expr.Expr) -> typing.NoReturn:
|
43
|
+
raise CircuitError(f"no cast is possible from '{rvalue.type}' to '{lvalue.type}'")
|
44
|
+
|
45
|
+
|
46
|
+
_HANDLE_CAST = {
|
47
|
+
types.CastKind.EQUAL: _handle_equal_types,
|
48
|
+
types.CastKind.IMPLICIT: _handle_implicit_cast,
|
49
|
+
types.CastKind.LOSSLESS: _requires_lossless_cast,
|
50
|
+
types.CastKind.DANGEROUS: _requires_dangerous_cast,
|
51
|
+
types.CastKind.NONE: _no_cast_possible,
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
class Store(Instruction):
|
56
|
+
"""A manual storage of some classical value to a classical memory location.
|
57
|
+
|
58
|
+
This is a low-level primitive of the classical-expression handling (similar to how
|
59
|
+
:class:`~.circuit.Measure` is a primitive for quantum measurement), and is not safe for
|
60
|
+
subclassing."""
|
61
|
+
|
62
|
+
# This is a compiler/backend intrinsic operation, separate to any quantum processing.
|
63
|
+
_directive = True
|
64
|
+
|
65
|
+
def __init__(self, lvalue: expr.Expr, rvalue: expr.Expr):
|
66
|
+
"""
|
67
|
+
Args:
|
68
|
+
lvalue: the memory location being stored into.
|
69
|
+
rvalue: the expression result being stored.
|
70
|
+
"""
|
71
|
+
if not expr.is_lvalue(lvalue):
|
72
|
+
raise CircuitError(f"'{lvalue}' is not an l-value")
|
73
|
+
|
74
|
+
cast_kind = types.cast_kind(rvalue.type, lvalue.type)
|
75
|
+
if (handler := _HANDLE_CAST.get(cast_kind)) is None:
|
76
|
+
raise RuntimeError(f"unhandled cast kind required: {cast_kind}")
|
77
|
+
lvalue, rvalue = handler(lvalue, rvalue)
|
78
|
+
|
79
|
+
super().__init__("store", 0, 0, [lvalue, rvalue])
|
80
|
+
|
81
|
+
@property
|
82
|
+
def lvalue(self):
|
83
|
+
"""Get the l-value :class:`~.expr.Expr` node that is being stored to."""
|
84
|
+
return self.params[0]
|
85
|
+
|
86
|
+
@property
|
87
|
+
def rvalue(self):
|
88
|
+
"""Get the r-value :class:`~.expr.Expr` node that is being written into the l-value."""
|
89
|
+
return self.params[1]
|
90
|
+
|
91
|
+
def c_if(self, classical, val):
|
92
|
+
""":meta hidden:"""
|
93
|
+
raise NotImplementedError(
|
94
|
+
"stores cannot be conditioned with `c_if`; use a full `if_test` context instead"
|
95
|
+
)
|
qiskit/compiler/assembler.py
CHANGED
@@ -350,20 +350,20 @@ def _parse_common_args(
|
|
350
350
|
]
|
351
351
|
|
352
352
|
# create run configuration and populate
|
353
|
-
run_config_dict =
|
354
|
-
shots
|
355
|
-
memory
|
356
|
-
seed_simulator
|
357
|
-
init_qubits
|
358
|
-
rep_delay
|
359
|
-
qubit_lo_freq
|
360
|
-
meas_lo_freq
|
361
|
-
qubit_lo_range
|
362
|
-
meas_lo_range
|
363
|
-
schedule_los
|
364
|
-
n_qubits
|
353
|
+
run_config_dict = {
|
354
|
+
"shots": shots,
|
355
|
+
"memory": memory,
|
356
|
+
"seed_simulator": seed_simulator,
|
357
|
+
"init_qubits": init_qubits,
|
358
|
+
"rep_delay": rep_delay,
|
359
|
+
"qubit_lo_freq": qubit_lo_freq,
|
360
|
+
"meas_lo_freq": meas_lo_freq,
|
361
|
+
"qubit_lo_range": qubit_lo_range,
|
362
|
+
"meas_lo_range": meas_lo_range,
|
363
|
+
"schedule_los": schedule_los,
|
364
|
+
"n_qubits": n_qubits,
|
365
365
|
**run_config,
|
366
|
-
|
366
|
+
}
|
367
367
|
|
368
368
|
return qobj_id, qobj_header, run_config_dict
|
369
369
|
|
@@ -452,15 +452,15 @@ def _parse_pulse_args(
|
|
452
452
|
parametric_pulses = getattr(backend_config, "parametric_pulses", [])
|
453
453
|
|
454
454
|
# create run configuration and populate
|
455
|
-
run_config_dict =
|
456
|
-
meas_level
|
457
|
-
meas_return
|
458
|
-
meas_map
|
459
|
-
memory_slot_size
|
460
|
-
rep_time
|
461
|
-
parametric_pulses
|
455
|
+
run_config_dict = {
|
456
|
+
"meas_level": meas_level,
|
457
|
+
"meas_return": meas_return,
|
458
|
+
"meas_map": meas_map,
|
459
|
+
"memory_slot_size": memory_slot_size,
|
460
|
+
"rep_time": rep_time,
|
461
|
+
"parametric_pulses": parametric_pulses,
|
462
462
|
**run_config,
|
463
|
-
|
463
|
+
}
|
464
464
|
run_config = RunConfig(**{k: v for k, v in run_config_dict.items() if v is not None})
|
465
465
|
|
466
466
|
return run_config
|
@@ -478,7 +478,7 @@ def _parse_circuit_args(
|
|
478
478
|
"""
|
479
479
|
parameter_binds = parameter_binds or []
|
480
480
|
# create run configuration and populate
|
481
|
-
run_config_dict =
|
481
|
+
run_config_dict = {"parameter_binds": parameter_binds, **run_config}
|
482
482
|
if parametric_pulses is None:
|
483
483
|
if backend:
|
484
484
|
run_config_dict["parametric_pulses"] = getattr(
|
qiskit/compiler/transpiler.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
|
@@ -24,6 +24,7 @@ from qiskit.circuit.quantumcircuit import QuantumCircuit
|
|
24
24
|
from qiskit.circuit.quantumregister import Qubit
|
25
25
|
from qiskit.dagcircuit import DAGCircuit
|
26
26
|
from qiskit.providers.backend import Backend
|
27
|
+
from qiskit.providers.backend_compat import BackendV2Converter
|
27
28
|
from qiskit.providers.models import BackendProperties
|
28
29
|
from qiskit.pulse import Schedule, InstructionScheduleMap
|
29
30
|
from qiskit.transpiler import Layout, CouplingMap, PropertySet
|
@@ -72,9 +73,32 @@ def transpile( # pylint: disable=too-many-return-statements
|
|
72
73
|
"""Transpile one or more circuits, according to some desired transpilation targets.
|
73
74
|
|
74
75
|
Transpilation is potentially done in parallel using multiprocessing when ``circuits``
|
75
|
-
is a list with > 1 :class:`~.QuantumCircuit` object depending on the local environment
|
76
|
+
is a list with > 1 :class:`~.QuantumCircuit` object, depending on the local environment
|
76
77
|
and configuration.
|
77
78
|
|
79
|
+
The prioritization of transpilation target constraints works as follows: if a ``target``
|
80
|
+
input is provided, it will take priority over any ``backend`` input or loose constraints
|
81
|
+
(``basis_gates``, ``inst_map``, ``coupling_map``, ``backend_properties``, ``instruction_durations``,
|
82
|
+
``dt`` or ``timing_constraints``). If a ``backend`` is provided together with any loose constraint
|
83
|
+
from the list above, the loose constraint will take priority over the corresponding backend
|
84
|
+
constraint. This behavior is independent of whether the ``backend`` instance is of type
|
85
|
+
:class:`.BackendV1` or :class:`.BackendV2`, as summarized in the table below. The first column
|
86
|
+
in the table summarizes the potential user-provided constraints, and each cell shows whether
|
87
|
+
the priority is assigned to that specific constraint input or another input
|
88
|
+
(`target`/`backend(V1)`/`backend(V2)`).
|
89
|
+
|
90
|
+
============================ ========= ======================== =======================
|
91
|
+
User Provided target backend(V1) backend(V2)
|
92
|
+
============================ ========= ======================== =======================
|
93
|
+
**basis_gates** target basis_gates basis_gates
|
94
|
+
**coupling_map** target coupling_map coupling_map
|
95
|
+
**instruction_durations** target instruction_durations instruction_durations
|
96
|
+
**inst_map** target inst_map inst_map
|
97
|
+
**dt** target dt dt
|
98
|
+
**timing_constraints** target timing_constraints timing_constraints
|
99
|
+
**backend_properties** target backend_properties backend_properties
|
100
|
+
============================ ========= ======================== =======================
|
101
|
+
|
78
102
|
Args:
|
79
103
|
circuits: Circuit(s) to transpile
|
80
104
|
backend: If set, the transpiler will compile the input circuit to this target
|
@@ -293,6 +317,12 @@ def transpile( # pylint: disable=too-many-return-statements
|
|
293
317
|
config = user_config.get_config()
|
294
318
|
optimization_level = config.get("transpile_optimization_level", 1)
|
295
319
|
|
320
|
+
if backend is not None and getattr(backend, "version", 0) <= 1:
|
321
|
+
# This is a temporary conversion step to allow for a smoother transition
|
322
|
+
# to a fully target-based transpiler pipeline while maintaining the behavior
|
323
|
+
# of `transpile` with BackendV1 inputs.
|
324
|
+
backend = BackendV2Converter(backend)
|
325
|
+
|
296
326
|
if (
|
297
327
|
scheduling_method is not None
|
298
328
|
and backend is None
|
@@ -307,7 +337,7 @@ def transpile( # pylint: disable=too-many-return-statements
|
|
307
337
|
|
308
338
|
_skip_target = False
|
309
339
|
_given_inst_map = bool(inst_map) # check before inst_map is overwritten
|
310
|
-
# If a target is specified have it override any implicit selections from a backend
|
340
|
+
# If a target is specified, have it override any implicit selections from a backend
|
311
341
|
if target is not None:
|
312
342
|
if coupling_map is None:
|
313
343
|
coupling_map = target.build_coupling_map()
|
@@ -324,9 +354,17 @@ def transpile( # pylint: disable=too-many-return-statements
|
|
324
354
|
if backend_properties is None:
|
325
355
|
backend_properties = target_to_backend_properties(target)
|
326
356
|
# If target is not specified and any hardware constraint object is
|
327
|
-
# manually specified
|
328
|
-
# it is invalidated by a custom basis gate list
|
329
|
-
|
357
|
+
# manually specified, do not use the target from the backend as
|
358
|
+
# it is invalidated by a custom basis gate list, custom coupling map,
|
359
|
+
# custom dt or custom instruction_durations
|
360
|
+
elif (
|
361
|
+
basis_gates is not None # pylint: disable=too-many-boolean-expressions
|
362
|
+
or coupling_map is not None
|
363
|
+
or dt is not None
|
364
|
+
or instruction_durations is not None
|
365
|
+
or backend_properties is not None
|
366
|
+
or timing_constraints is not None
|
367
|
+
):
|
330
368
|
_skip_target = True
|
331
369
|
else:
|
332
370
|
target = getattr(backend, "target", None)
|
@@ -341,6 +379,7 @@ def transpile( # pylint: disable=too-many-return-statements
|
|
341
379
|
_check_circuits_coupling_map(circuits, coupling_map, backend)
|
342
380
|
|
343
381
|
timing_constraints = _parse_timing_constraints(backend, timing_constraints)
|
382
|
+
instruction_durations = _parse_instruction_durations(backend, instruction_durations, dt)
|
344
383
|
|
345
384
|
if _given_inst_map and inst_map.has_custom_gate() and target is not None:
|
346
385
|
# Do not mutate backend target
|
@@ -353,51 +392,6 @@ def transpile( # pylint: disable=too-many-return-statements
|
|
353
392
|
if translation_method is None and hasattr(backend, "get_translation_stage_plugin"):
|
354
393
|
translation_method = backend.get_translation_stage_plugin()
|
355
394
|
|
356
|
-
if instruction_durations or dt:
|
357
|
-
# If durations are provided and there is more than one circuit
|
358
|
-
# we need to serialize the execution because the full durations
|
359
|
-
# is dependent on the circuit calibrations which are per circuit
|
360
|
-
if len(circuits) > 1:
|
361
|
-
out_circuits = []
|
362
|
-
for circuit in circuits:
|
363
|
-
instruction_durations = _parse_instruction_durations(
|
364
|
-
backend, instruction_durations, dt, circuit
|
365
|
-
)
|
366
|
-
pm = generate_preset_pass_manager(
|
367
|
-
optimization_level,
|
368
|
-
backend=backend,
|
369
|
-
target=target,
|
370
|
-
basis_gates=basis_gates,
|
371
|
-
inst_map=inst_map,
|
372
|
-
coupling_map=coupling_map,
|
373
|
-
instruction_durations=instruction_durations,
|
374
|
-
backend_properties=backend_properties,
|
375
|
-
timing_constraints=timing_constraints,
|
376
|
-
initial_layout=initial_layout,
|
377
|
-
layout_method=layout_method,
|
378
|
-
routing_method=routing_method,
|
379
|
-
translation_method=translation_method,
|
380
|
-
scheduling_method=scheduling_method,
|
381
|
-
approximation_degree=approximation_degree,
|
382
|
-
seed_transpiler=seed_transpiler,
|
383
|
-
unitary_synthesis_method=unitary_synthesis_method,
|
384
|
-
unitary_synthesis_plugin_config=unitary_synthesis_plugin_config,
|
385
|
-
hls_config=hls_config,
|
386
|
-
init_method=init_method,
|
387
|
-
optimization_method=optimization_method,
|
388
|
-
_skip_target=_skip_target,
|
389
|
-
)
|
390
|
-
out_circuits.append(pm.run(circuit, callback=callback, num_processes=num_processes))
|
391
|
-
for name, circ in zip(output_name, out_circuits):
|
392
|
-
circ.name = name
|
393
|
-
end_time = time()
|
394
|
-
_log_transpile_time(start_time, end_time)
|
395
|
-
return out_circuits
|
396
|
-
else:
|
397
|
-
instruction_durations = _parse_instruction_durations(
|
398
|
-
backend, instruction_durations, dt, circuits[0]
|
399
|
-
)
|
400
|
-
|
401
395
|
pm = generate_preset_pass_manager(
|
402
396
|
optimization_level,
|
403
397
|
backend=backend,
|
@@ -422,7 +416,7 @@ def transpile( # pylint: disable=too-many-return-statements
|
|
422
416
|
optimization_method=optimization_method,
|
423
417
|
_skip_target=_skip_target,
|
424
418
|
)
|
425
|
-
out_circuits = pm.run(circuits, callback=callback)
|
419
|
+
out_circuits = pm.run(circuits, callback=callback, num_processes=num_processes)
|
426
420
|
for name, circ in zip(output_name, out_circuits):
|
427
421
|
circ.name = name
|
428
422
|
end_time = time()
|
@@ -440,14 +434,8 @@ def _check_circuits_coupling_map(circuits, cmap, backend):
|
|
440
434
|
if cmap is not None:
|
441
435
|
max_qubits = cmap.size()
|
442
436
|
elif backend is not None:
|
443
|
-
|
444
|
-
|
445
|
-
if not backend.configuration().simulator:
|
446
|
-
max_qubits = backend.configuration().n_qubits
|
447
|
-
else:
|
448
|
-
max_qubits = None
|
449
|
-
else:
|
450
|
-
max_qubits = backend.num_qubits
|
437
|
+
max_qubits = backend.num_qubits
|
438
|
+
|
451
439
|
for circuit in circuits:
|
452
440
|
# If coupling_map is not None or num_qubits == 1
|
453
441
|
num_qubits = len(circuit.qubits)
|
@@ -465,27 +453,15 @@ def _log_transpile_time(start_time, end_time):
|
|
465
453
|
|
466
454
|
def _parse_inst_map(inst_map, backend):
|
467
455
|
# try getting inst_map from user, else backend
|
468
|
-
if inst_map is None:
|
469
|
-
|
470
|
-
if backend_version <= 1:
|
471
|
-
if hasattr(backend, "defaults"):
|
472
|
-
inst_map = getattr(backend.defaults(), "instruction_schedule_map", None)
|
473
|
-
else:
|
474
|
-
inst_map = backend.target.instruction_schedule_map()
|
456
|
+
if inst_map is None and backend is not None:
|
457
|
+
inst_map = backend.target.instruction_schedule_map()
|
475
458
|
return inst_map
|
476
459
|
|
477
460
|
|
478
461
|
def _parse_coupling_map(coupling_map, backend):
|
479
462
|
# try getting coupling_map from user, else backend
|
480
|
-
if coupling_map is None:
|
481
|
-
|
482
|
-
if backend_version <= 1:
|
483
|
-
if getattr(backend, "configuration", None):
|
484
|
-
configuration = backend.configuration()
|
485
|
-
if hasattr(configuration, "coupling_map") and configuration.coupling_map:
|
486
|
-
coupling_map = CouplingMap(configuration.coupling_map)
|
487
|
-
else:
|
488
|
-
coupling_map = backend.coupling_map
|
463
|
+
if coupling_map is None and backend is not None:
|
464
|
+
coupling_map = backend.coupling_map
|
489
465
|
|
490
466
|
# coupling_map could be None, or a list of lists, e.g. [[0, 1], [2, 1]]
|
491
467
|
if coupling_map is None or isinstance(coupling_map, CouplingMap):
|
@@ -515,38 +491,20 @@ def _parse_initial_layout(initial_layout):
|
|
515
491
|
return initial_layout
|
516
492
|
|
517
493
|
|
518
|
-
def _parse_instruction_durations(backend, inst_durations, dt
|
494
|
+
def _parse_instruction_durations(backend, inst_durations, dt):
|
519
495
|
"""Create a list of ``InstructionDuration``s. If ``inst_durations`` is provided,
|
520
496
|
the backend will be ignored, otherwise, the durations will be populated from the
|
521
|
-
backend.
|
522
|
-
take precedence over backend durations, but be superceded by ``inst_duration``s.
|
497
|
+
backend.
|
523
498
|
"""
|
499
|
+
final_durations = InstructionDurations()
|
524
500
|
if not inst_durations:
|
525
|
-
|
526
|
-
if
|
527
|
-
backend_durations = InstructionDurations()
|
528
|
-
try:
|
529
|
-
backend_durations = InstructionDurations.from_backend(backend)
|
530
|
-
except AttributeError:
|
531
|
-
pass
|
532
|
-
else:
|
501
|
+
backend_durations = InstructionDurations()
|
502
|
+
if backend is not None:
|
533
503
|
backend_durations = backend.instruction_durations
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
if circuit.calibrations:
|
540
|
-
cal_durations = []
|
541
|
-
for gate, gate_cals in circuit.calibrations.items():
|
542
|
-
for (qubits, parameters), schedule in gate_cals.items():
|
543
|
-
cal_durations.append((gate, qubits, parameters, schedule.duration))
|
544
|
-
circ_durations.update(cal_durations, circ_durations.dt)
|
545
|
-
|
546
|
-
if inst_durations:
|
547
|
-
circ_durations.update(inst_durations, dt or getattr(inst_durations, "dt", None))
|
548
|
-
|
549
|
-
return circ_durations
|
504
|
+
final_durations.update(backend_durations, dt or backend_durations.dt)
|
505
|
+
else:
|
506
|
+
final_durations.update(inst_durations, dt or getattr(inst_durations, "dt", None))
|
507
|
+
return final_durations
|
550
508
|
|
551
509
|
|
552
510
|
def _parse_approximation_degree(approximation_degree):
|
@@ -598,13 +556,6 @@ def _parse_timing_constraints(backend, timing_constraints):
|
|
598
556
|
return timing_constraints
|
599
557
|
if backend is None and timing_constraints is None:
|
600
558
|
timing_constraints = TimingConstraints()
|
601
|
-
|
602
|
-
|
603
|
-
if backend_version <= 1:
|
604
|
-
if timing_constraints is None:
|
605
|
-
# get constraints from backend
|
606
|
-
timing_constraints = getattr(backend.configuration(), "timing_constraints", {})
|
607
|
-
timing_constraints = TimingConstraints(**timing_constraints)
|
608
|
-
else:
|
609
|
-
timing_constraints = backend.target.timing_constraints()
|
559
|
+
elif backend is not None:
|
560
|
+
timing_constraints = backend.target.timing_constraints()
|
610
561
|
return timing_constraints
|
qiskit/converters/__init__.py
CHANGED
@@ -17,12 +17,27 @@ Circuit Converters (:mod:`qiskit.converters`)
|
|
17
17
|
|
18
18
|
.. currentmodule:: qiskit.converters
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
QuantumCircuit -> circuit components
|
21
|
+
====================================
|
22
|
+
|
22
23
|
.. autofunction:: circuit_to_instruction
|
23
24
|
.. autofunction:: circuit_to_gate
|
25
|
+
|
26
|
+
QuantumCircuit <-> DagCircuit
|
27
|
+
=============================
|
28
|
+
|
29
|
+
.. autofunction:: circuit_to_dag
|
30
|
+
.. autofunction:: dag_to_circuit
|
31
|
+
|
32
|
+
QuantumCircuit <-> DagDependency
|
33
|
+
================================
|
34
|
+
|
24
35
|
.. autofunction:: dagdependency_to_circuit
|
25
36
|
.. autofunction:: circuit_to_dagdependency
|
37
|
+
|
38
|
+
DagCircuit <-> DagDependency
|
39
|
+
============================
|
40
|
+
|
26
41
|
.. autofunction:: dag_to_dagdependency
|
27
42
|
.. autofunction:: dagdependency_to_dag
|
28
43
|
"""
|
@@ -79,6 +79,13 @@ def circuit_to_dag(circuit, copy_operations=True, *, qubit_order=None, clbit_ord
|
|
79
79
|
dagcircuit.add_qubits(qubits)
|
80
80
|
dagcircuit.add_clbits(clbits)
|
81
81
|
|
82
|
+
for var in circuit.iter_input_vars():
|
83
|
+
dagcircuit.add_input_var(var)
|
84
|
+
for var in circuit.iter_captured_vars():
|
85
|
+
dagcircuit.add_captured_var(var)
|
86
|
+
for var in circuit.iter_declared_vars():
|
87
|
+
dagcircuit.add_declared_var(var)
|
88
|
+
|
82
89
|
for register in circuit.qregs:
|
83
90
|
dagcircuit.add_qreg(register)
|
84
91
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2020.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""Helper function for converting a circuit to a dag dependency"""
|
14
|
+
|
15
|
+
from qiskit.dagcircuit.dagdependency_v2 import _DAGDependencyV2
|
16
|
+
|
17
|
+
|
18
|
+
def _circuit_to_dagdependency_v2(circuit):
|
19
|
+
"""Build a ``_DAGDependencyV2`` object from a :class:`~.QuantumCircuit`.
|
20
|
+
|
21
|
+
Args:
|
22
|
+
circuit (QuantumCircuit): the input circuit.
|
23
|
+
|
24
|
+
Return:
|
25
|
+
_DAGDependencyV2: the DAG representing the input circuit as a dag dependency.
|
26
|
+
"""
|
27
|
+
dagdependency = _DAGDependencyV2()
|
28
|
+
dagdependency.name = circuit.name
|
29
|
+
dagdependency.metadata = circuit.metadata
|
30
|
+
dagdependency.calibrations = circuit.calibrations
|
31
|
+
dagdependency.global_phase = circuit.global_phase
|
32
|
+
|
33
|
+
dagdependency.add_qubits(circuit.qubits)
|
34
|
+
dagdependency.add_clbits(circuit.clbits)
|
35
|
+
|
36
|
+
for register in circuit.qregs:
|
37
|
+
dagdependency.add_qreg(register)
|
38
|
+
|
39
|
+
for register in circuit.cregs:
|
40
|
+
dagdependency.add_creg(register)
|
41
|
+
|
42
|
+
for instruction in circuit.data:
|
43
|
+
dagdependency.apply_operation_back(
|
44
|
+
instruction.operation, instruction.qubits, instruction.clbits
|
45
|
+
)
|
46
|
+
|
47
|
+
return dagdependency
|
@@ -58,6 +58,8 @@ def circuit_to_gate(circuit, parameter_map=None, equivalence_library=None, label
|
|
58
58
|
|
59
59
|
if circuit.clbits:
|
60
60
|
raise QiskitError("Circuit with classical bits cannot be converted to gate.")
|
61
|
+
if circuit.num_vars:
|
62
|
+
raise QiskitError("circuits with realtime classical variables cannot be converted to gates")
|
61
63
|
|
62
64
|
for instruction in circuit.data:
|
63
65
|
if not _check_is_gate(instruction.operation):
|
@@ -61,6 +61,28 @@ def circuit_to_instruction(circuit, parameter_map=None, equivalence_library=None
|
|
61
61
|
# pylint: disable=cyclic-import
|
62
62
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
63
63
|
|
64
|
+
if circuit.num_input_vars:
|
65
|
+
# This could be supported by moving the `input` variables to be parameters of the
|
66
|
+
# instruction, but we don't really have a good reprssentation of that yet, so safer to
|
67
|
+
# forbid it.
|
68
|
+
raise QiskitError("Circuits with 'input' variables cannot yet be converted to instructions")
|
69
|
+
if circuit.num_captured_vars:
|
70
|
+
raise QiskitError("Circuits that capture variables cannot be converted to instructions")
|
71
|
+
if circuit.num_declared_vars:
|
72
|
+
# This could very easily be supported in representations, since the variables are allocated
|
73
|
+
# and freed within the instruction itself. The reason to initially forbid it is to avoid
|
74
|
+
# needing to support unrolling such instructions within the transpiler; we would potentially
|
75
|
+
# need to remap variables to unique names in the larger context, and we don't yet have a way
|
76
|
+
# to return that information from the transpiler. We have to catch that in the transpiler
|
77
|
+
# as well since a user could manually make an instruction with such a definition, but
|
78
|
+
# forbidding it here means users get a more meaningful error at the point that the
|
79
|
+
# instruction actually gets created (since users often aren't aware that
|
80
|
+
# `QuantumCircuit.append(QuantumCircuit)` implicitly converts to an instruction).
|
81
|
+
raise QiskitError(
|
82
|
+
"Circuits with internal variables cannot yet be converted to instructions."
|
83
|
+
" You may be able to use `QuantumCircuit.compose` to inline this circuit into another."
|
84
|
+
)
|
85
|
+
|
64
86
|
if parameter_map is None:
|
65
87
|
parameter_dict = {p: p for p in circuit.parameters}
|
66
88
|
else:
|
@@ -62,7 +62,11 @@ def dag_to_circuit(dag, copy_operations=True):
|
|
62
62
|
*dag.cregs.values(),
|
63
63
|
name=name,
|
64
64
|
global_phase=dag.global_phase,
|
65
|
+
inputs=dag.iter_input_vars(),
|
66
|
+
captures=dag.iter_captured_vars(),
|
65
67
|
)
|
68
|
+
for var in dag.iter_declared_vars():
|
69
|
+
circuit.add_uninitialized_var(var)
|
66
70
|
circuit.metadata = dag.metadata
|
67
71
|
circuit.calibrations = dag.calibrations
|
68
72
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2020.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""Helper function for converting a dag circuit to a dag dependency"""
|
14
|
+
from qiskit.dagcircuit.dagdependency_v2 import _DAGDependencyV2
|
15
|
+
|
16
|
+
|
17
|
+
def _dag_to_dagdependency_v2(dag):
|
18
|
+
"""Build a ``_DAGDependencyV2`` object from a ``DAGCircuit``.
|
19
|
+
|
20
|
+
Args:
|
21
|
+
dag (DAGCircuit): the input dag.
|
22
|
+
|
23
|
+
Return:
|
24
|
+
_DAGDependencyV2: the DAG representing the input circuit as a dag dependency.
|
25
|
+
"""
|
26
|
+
dagdependency = _DAGDependencyV2()
|
27
|
+
dagdependency.name = dag.name
|
28
|
+
dagdependency.metadata = dag.metadata
|
29
|
+
dagdependency.global_phase = dag.global_phase
|
30
|
+
dagdependency.calibrations = dag.calibrations
|
31
|
+
|
32
|
+
dagdependency.add_qubits(dag.qubits)
|
33
|
+
dagdependency.add_clbits(dag.clbits)
|
34
|
+
|
35
|
+
for register in dag.qregs.values():
|
36
|
+
dagdependency.add_qreg(register)
|
37
|
+
|
38
|
+
for register in dag.cregs.values():
|
39
|
+
dagdependency.add_creg(register)
|
40
|
+
|
41
|
+
for node in dag.topological_op_nodes():
|
42
|
+
dagdependency.apply_operation_back(node.op.copy(), node.qargs, node.cargs)
|
43
|
+
|
44
|
+
return dagdependency
|